MISRA Discussion Forums
Rule 10.4 and essentially signed integer constant expressions - Printable Version

+- MISRA Discussion Forums (https://forum.misra.org.uk)
+-- Forum: MISRA C (https://forum.misra.org.uk/forumdisplay.php?fid=4)
+--- Forum: MISRA C:2012 and MISRA C:2023 guidelines (https://forum.misra.org.uk/forumdisplay.php?fid=21)
+---- Forum: 8.10 The essential type model (https://forum.misra.org.uk/forumdisplay.php?fid=165)
+---- Thread: Rule 10.4 and essentially signed integer constant expressions (/showthread.php?tid=1559)



Rule 10.4 and essentially signed integer constant expressions - jaska - 19-01-2021

Rule 10.3 exception 1 allows assigning a signed integer constant expression to an essentially unsigned type, if the value can be represented in that type; u8 = 2 * 24; is allowed.
Rule 10.4 has no such exception
Expressions like u32 > 0, u8 != 0, and u32 += 1 violate rule 10.4.

Now:

uint32_t u32idem(uint32_t x) { return x; }
bool less_u32(uint32_t a, uint32_b ) { return a < b; }

if (u32 < u32idem(1)) { /* accepted by 10.3 and 10.4 */
} else if (less_u32(u32, 3)) { /* accepted by 10.3 (and 10.4) */
} else if (u32 < 4u) { /* fine by 10.4 */
} else if (u32 < 7) { /* violates 10.4 */
} else if (11u > u32) { /* ok, remove u and it's not */
} else {
switch (u32) {
case 23: /* ok */
...

Why are binary operators handled differently from assignments and switch cases? I think the exception should be the same for both 10.3 and 10.4 ?

Why is there no exception for Rule 10.4 allowing an integer constant expression to be used in a binary expression?


RE: Rule 10.4 and essentially signed integer constant expressions - misra-c - 13-02-2022

C performs different integer promotions on balancing operands ( e.g. > ) as compared to the operands of assigning conversions, which include switch cases.

For balancing operators, each operand is first promoted using the "integer promotion" rules and then the two operands are balanced to a common type using the "usual arithmetic conversions".
For assigning operators, the RH operand (or case expression) is converted to the type of the LH operand (or the promoted switch chooser)

For Example - assuming 8 bit char, 16 bit short and 32 bit int
Code:
  unsigned char u8;
  u8 * 32767   
    // u8 is promoted to signed int, 32767 has type signed int. 
    // Operation takes place in signed int leading to undefined behaviour if u8 > 1
  u8 * 32767U 
    // u8 is promoted to signed int,  32767U has type unsigned int.
    // Operation takes place in unsigned int which leads to a defined wrapped value if u8 > 1
Rule 10.3 on assigning operations has different exceptions to rule 10.4 on balancing operations because the conversions in C are quite different.  The C type of an integer constant expression will effect the resultant C type of a balancing conversion, but it will not effect the resultant type of an assignment.