MISRA-C error in struct array initialization

浪尽此生 提交于 2019-12-23 08:02:14


I have the following:

typedef struct
   uint8_t BlockID;
   uint32_t Copies;
   uint16_t Size;

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},


(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.


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.


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},