MISRA-C error in struct array initialization
Asked Answered
C

3

8

I have the following:

typedef struct
{
   uint8_t BlockID;
   uint32_t Copies;
   uint16_t Size;
}NVMM_ConfigType;

const NVMM_ConfigType NvmmCnf_Layout[6] =
{
   {  1, 1,   4},
   {  2, 3,   4},
   {  5, 5,  16},
   { 10, 1,   4},
   { 11, 2,  32},
   { 13, 1, 100},
};

Which seems fine to me, but, MISRA-C is giving the following error:

MISRA C:2012 rule 10.3 violation: [R] The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category

I've tried to figure out why is this happening but I just can see it. Also the build results are plagued with this errors on similar situations and I don't know why.

Does anybody know what's going on?

EDIT: I have also tried to explicitly cast every value and still getting the same error:

const NVMM_ConfigType NvmmCnf_Layout[6] =
{
    {  (uint8_t)1, (uint32_t)1,   (uint16_t)4},
    {  (uint8_t)2, (uint32_t)3,   (uint16_t)4},
    {  (uint8_t)5, (uint32_t)5,  (uint16_t)16},
    { (uint8_t)10, (uint32_t)1,   (uint16_t)4},
    { (uint8_t)11, (uint32_t)2,  (uint16_t)32},
    { (uint8_t)13, (uint32_t)1, (uint16_t)100},
};
Controvert answered 30/7, 2015 at 14:43 Comment(4)
I don't see any problem here... certainly not wrt R10.3. Which line is the error against?Langsdon
Please show your version of the code with type casts referenced in a comment below, "I've also tried to cast every single value but still getting the same error."Foison
@Andrew: The error is at the opening brace, the one right after the "="Controvert
@Controvert I noticed your latest edit, spending time to silence a tool when you know it makes no sense and makes the code overly verbose is actually non-compliant ;-)Meteoric
M
5

(Hi, this is a new account so I cannot use the comments section yet to ask for further clarification, so pardon the long reply)

To be specific, this Rule 10.3 pertains to MISRA-C:2012 (the latest standard) which is a great improvement over the prior versions in that there is more effort in explaining MISRA's rationale, along with many more compliant and non-compliant examples.

The rationale of the rule is: since C permits assignments between different arithmetic types to be performed automatically, the use of these implicit conversions can lead to unintended results, with the potential for loss of value, sign or precision. MISRA_C:2012 has an essential type model to help warn when this might occur.

The rule descriptions also include exceptions to the rule. For Rule 10.3, one exception is: A non-negative integer constant expression of essentially signed type may be assigned to an object of essentially unsigned type if its value can be represented in that type.

Its not clear what the exact line and column your tool is reporting the violation on (it should). The better of the tools will also provide more detailed information on exactly what part of the rule is being violated (e.g. if instead of a 1, you had 128 in the first assignment to a 8-bit, the tool should be very explicit about that).

In any case, I don’t (nor does my tool) see any violation of 10.3 here.

Since this is a “decidable” rule, I would be concerned about the tool if this is safety-critical code, besides the fact that it is wasting your time.

Most tools allow you to suppress a warning and document the reason (in this case it is a bug in the tool).

If your tool vendor needs further information, you can post your question in the discussions forum at http://www.misra-c.com to get the official answer and forward that to the vendor.

Meteoric answered 31/7, 2015 at 21:21 Comment(2)
Thanks and I'll let the vendor know because I think the tool has come issues with MISRA-C. By the way, the tool is the TriCore Eclipse IDE v5.0r2 from AltiumControvert
As I said, The MISRA-C:2012 is a great improvement and as a result its becoming the base C coding standard for other safety critical industries (besides automobile). However, the MISRA organization doesn't have a certification or conformance program for the tools, its up to the users to figure out which ones best meet their needs and best help them fill out their compliance matrix.Meteoric
U
1

Hmm, that rule will make setting 8 bit registers actually impossible, as arithmetic operations are performed as int or larger (usual arithmetic conversions). One more reason to reject MISRA as coding standard.

I assume you have to cast every single value in the initializer to the type of the respective field. But As the rule is cited, that would still be a violation.

Unhandled answered 30/7, 2015 at 14:49 Comment(9)
I've also tried to cast every single value but still getting the same errorControvert
Can you explain why you think "that rule will make setting 8 bit registers actually impossible" ?Langsdon
@Andrew: I forgot about casts. Strange enough, as gcc warns about the same if usning -Wconversions. I'll delete the answer anyway soon, as it apparently does not help and I'm not a MISRA expert - I actually think it is a good reading for beginners to learn about the pitfalls, but not a good idea to take it religious as most of its apprentices do. A good compiler with most warnings enabled is much better and allows for some flexibility for the experienced programmer without restraining ;-) him too much.Unhandled
No-one should take it religious but should learn and understand the reason behind the guidelines...Langsdon
@Andrew: For that I fully agree. But many companies apparently have the idea that MISRA makes a bad programmer writing good code and good programmers even better. And defend this belief against all converse proof and reason.Unhandled
@Olaf - indeed... which is why we wrote the first six chapters of the book. But too many people read the Rules and ignore the rest!Langsdon
@Andrew: just had a peek at your profile. Didn't know you are one of the members actually. FWIW: I thnik the rules and explanations are really worth to read, but actually using MISRA would make my code less safe actually, as I use gcc extension which avoid many casts, while still maintaining type-safety. This is my major concern about MISRA (and also the code can become less readable sometimes). Never mind!Unhandled
Maybe we should move this to Chat... I'm interested to hear why you feel that way :-)Langsdon
@Olaf - please come to chat.stackoverflow.com/rooms/85390/misra-musings (Anyone else is welcome too)Langsdon
F
0

When I use PC-Lint to check Misra rules, I often find myself needing to add u suffix to constants:

const NVMM_ConfigType NvmmCnf_Layout[6] =
{
   {  1u, 1u,   4u},
   {  2u, 3u,   4u},
   {  5u, 5u,  16u},
   { 10u, 1u,   4u},
   { 11u, 2u,  32u},
   { 13u, 1u, 100u},
};

This eliminates the int to unsigned conversion.

If this isn't enough, then casts:

const NVMM_ConfigType NvmmCnf_Layout[6] =
{
   { (uint8_t ) 1u, 1u, (uint16_t )  4u},
   { (uint8_t ) 2u, 3u, (uint16_t )  4u},
   { (uint8_t ) 5u, 5u, (uint16_t ) 16u},
   { (uint8_t )10u, 1u, (uint16_t )  4u},
   { (uint8_t )11u, 2u, (uint16_t ) 32u},
   { (uint8_t )13u, 1u, (uint16_t )100u},
};
Foison answered 6/8, 2015 at 12:35 Comment(5)
I have also tried these two options and still failing. Everything leads to the conclusion that the tool is not working properly.Controvert
@Doug This is MISRA-C:2012, not MISRA-C:2004.Meteoric
@Veriloud, your statement is true, but I don't understand how it pertains to my answer. Are you saying that using PC-Lint for MISRA-C:2012 compliance does not have this issue?Foison
@Doug, yes, it is a MISRA 2004 violation, but it is superfluous, and MISRA-C 2012 agrees, and why shouldn't it? I am a big fan of MISRA-C:2012 and this is one of the many reasons.Meteoric
If PC-Lint flags this as an MISRA-C:2012 issue, it is in error, but not surprising, it is not the best of its class.Meteoric

© 2022 - 2024 — McMap. All rights reserved.