MISRA Discussion Forums

Full Version: 10.3 Clarification on assigning unsigned literal to signed
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Quote: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.

While Rule 10.3 has this Exception for constructions similar to
uint8_t u8a = 0;    /* By exception */
there does not seem to be a similar exception for the inverse
int8_t s8a = 1u;    /* Compliant? */
Our current analysis tool flags this as an error, but this assignment seems no more dangerous than the one given by the Example. Is there a specific rationale for why this assignment should not be allowed, given the condition of the Exception
Quote:if its value can be represented in that type.
The exception was created for signed literals as coders frequently omit the "U" suffix and it seemed over harsh to prevent such assignments.

If a coder has added the suffix "U", this explicitly signals an intention that the literal should be "unsigned" and therefore should only used in an essentially unsigned context. The view of the working group was that assigning such literals to a signed object could indicate a programming error and should therefore raise a violation.
int8_t s8a = 1u;   /*Non-compliant */
hmm.. in my humble opinion, I see no real danger with that code.

If the "U" is removed, that is a ok fix. If a cast is added to fix the warning then I do see danger.

How do you feel if a cast is added like:
int8_t s8a = (int8_t)VALUE;

And then sometime in the future, the VALUE is changed to 256? Unless I am mistaken, there is no compiler/tool warning? The code will continue to "work".
The result of the cast "(int8_t)256U" is implementation-defined since 256 can not be represented by a signed 8-bit type. A tool supporting directive 1.1 may generate a warning in order to direct the user to document the behaviour of such a cast.

We would recommend removing the "U" rather than adding a cast.
int8_t s8a = 256;  // implicit narrowing conversion violates rule 10.3
An alternative would be to use a mask so that the value always fits the int8_t range.
int8_t s8a = (int8_t)(256U & 0xffU);