MISRA Discussion Forums

Full Version: Underlying type for integer constant expressions
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
The initialization:
uint8_t d = ((uint8_t) 0x1U) | ((uint8_t) 0x2U);
should, according to the MISRA-C guidelines, generate an error for rule 10.1. The initializer, i.e. the integer constant expression, has the underlying type of uint8_t, but that type is overruled by the explicit rule for integer constant expressions in 6.10.4 that says that the signedness/unsignedness of the underlying type should be taken from the actual type of the integer constant expression, but only if it is signed or unsigned int. In this case it is signed int. Giving the rule 10.1 breakage. Is this really the intention of the MISRA-C guidelines for integer constant expressions?
You are correct in stating that there is a conflict between Rule 10.1 and Section 6.10.4. This was not intentional.

You could write the expression as:

uint8_t d = (uint8_t)( 0x1U | 0x2U );

The underlying type of each of the constants, 0x1U and 0x2U, is unsigned int. The underlying type of the expression (0x1U | 0x2U) is also unsigned int. It is permitted to cast a constant expression because Rule 10.3 doesn't apply to constant expressions (Section 6.10.5) and, even if it did apply, a cast to a shorter unsigned type would be permitted by Rule 10.3.

An alternative would be to deviate Rule 10.1 in this situation.

The underlying type of integer constant expressions (as opposed to integer constants) is not handled properly in all cases in MISRA C 2004. The next revision of MISRA C will provide a more complete treatment of this subject.