Search code examples
cmisra

Why does redlib define INT8_MIN as (-0x80) and not as (-0x7F) or (-INT8_MAX - 1)


As the title says, REDLIB defines INT8_MIN as (-0x80). This is giving warnings when using QAC to check for MISRA-C compatibility: (the same goes for INT16 and INT32, which are -0x8000 and -0x80000000 respectively)

Msg(4:1281) Integer literal constant is of an unsigned type but does not include a "U" suffix.
MISRA-C:2004 Rule 10.6; REFERENCE - ISO:C90-6.1.3.2 (Integer Constants)

Msg(4:3101) Unary '-' applied to an operand of type unsigned int or unsigned long gives an unsigned result.
MISRA-C:2004 Rule 12.9; REFERENCE - ISO:C90-6.3.3.3 Unary Arithmetic Operators - Semantics

Msg(4:2850) Constant: Implicit conversion to a signed integer type of insufficient size.
MISRA-C:2004 Rule 3.1; REFERENCE - ISO:C90-6.2.1.2 Conversions (to Signed Integers)

Solution

  • There's a subtle rule about integer literals ("integer constants") in the C standard (C11 6.4.4.1) stating that if you write a plain integer literal such as 70000 without any U or L suffix, the type of the literal is determined as follows:

    • If the literal is large enough to be stored in an int, then it is of type int.
    • Otherwise if the literal is large enough to stored in a long, then it is of type long.
    • (Otherwise in case of C99/C11, the literal is of type long long).

    So 70000 on a 16-bit system would be of type long.

    But when you write a hexadecimal integer literal (or an octal one), different rules apply. Instead, the compiler is checking in this order:

    int
    unsigned int
    long int
    unsigned long int
    long long int
    unsigned long long int
    

    So when you write 0x8000 on a system where int is 16 bits, the compiler checks: Can it fit inside an int? No. Can it fit inside an unsigned int? Yes. The type of 0x8000 is therefore unsigned int and similarly 0x80000000 is of type unsigned long.

    This is why you get the MISRA errors for 0x8000 and 0x80000000, because it simply doesn't make any sense to apply unary - on an unsigned type. So that library is not MISRA-C compliant.

    However, the integer literal 0x80 is always of type int on any system. If you get a MISRA error on that line, your static analysis tool is broken for that rule. File a bug report to PRQA.