MISRA Discussion Forums

Full Version: Essential type of constant expressions
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
In MISRA-C:2012, it is stated that the essential type of the constant expression ~(unsigned short)3 is the UTLR of its value (i.e., -4), but the definition of UTLR seems not to cover this case (that is, the UTLR of -4 is undefined).

Another similar example is (unsigned char)3 - (unsigned char)4.

What is the essential type of these constant expressions?
This answer assumes that C types has the following sizes
Code:
unsigned char:  8 bits
  unsigned short: 16 bits
  unsigned int :  32 bits
First it is important to understand what is happening in terms of the C standard type.

The integer literal "3" is of type "signed int", which is then cast to "unsigned short". Before the "~" operator is called the "usual unary conversions" are applied to the operand and hence the "(unsigned char)3" is promoted back to have type "signed int".

Every bit in the 32-bit number is then inverted, and the type remains the same as the promoted type; in other words it remains as "signed int". On most machines that bit pattern will be equivalent to -4, but in general the value is implementation dependent.

In contrast the essential type of the operator "~" is essentially unsigned short. The operand is an integer constant expression, which means that essential type can be determined by looking at Appendix D.7 and paragraph 1.1 of the section on ~.
Quote:1. If the operand is essentially unsigned then:

1.1 If the operand is an integer constant expression then the essential type of the result is the UTLR of the result.
The result of the "~" operator has a well-defined bit pattern which corresponds to an unsigned value of 4294967292, and therefore has a UTLR of "unsigned int". The use of the result of the "~" operator may then violate other MISRA rules. For example assignment to a "signed int" object will violate rule 10.3. This protects the user from relying on a value that is implementation dependent.

Similarly "(unsigned char)3 - (unsigned char)4" will have a resultant C standard type of "signed int", but an essential type of "unsigned int". This is because the equivalent unsigned value will be be 4294967292, which gives a UTLR of "unsigned int". See paragraph 2.1 in Appendix D7 of the section on.
Quote:2. If the operands are both essentially unsigned then:

2.1 If the expression is an integer constant expression then the essential type of the result is the UTLR of the result.
Note: this expression will violate rule 12.4.