MISRA Violation 12.9 Operand of unary minus is unsigned

Viewed 268

I'm currently dealing with some MISRA issues and therefore trying to understand the integer conversion rules in C.

I'm getting a violation of MISRA-C 2004 rule 12.9 The unary minus operator shall not be applied to an expression whose underlying type is unsigned

in the code line

signed long int test = -1;

I understand that there is no negative integer constant "-1", but rather the unary minus applied to the integer constant "1" (as stated in https://en.cppreference.com/w/c/language/integer_constant).

The integer constant "1" however is of the first type in the list int, long int, unsigned long int (until C99), long long int (since C99)

I'm compling with Keil (ARM 32 bits) and the --c99 flag set, while MISRA-C 2004 seems to be based on the C90 standard.

So it seems as my SCA tool is assuming the "1" constant is of type unsigned long int (until C99), but I can't see, why it wouldn't fit in an ordinary int and therefore be signed.

To satisfy the SCA tool, one has to code

signed long int test = -1L;

or

signed long int test = -((signed long int) 1);

Is this correct behaviour or am I missing something here?

1 Answers

The integer constant "1" however is of the first type in the list int, long int, unsigned long int...

Correct. Integer constants like 1 are of type int and as far as MISRA-C is concerned, the underlying type is also int. The definition is (MISRA-C:2004 6.10.4)

The term "underlying type" is defined as describing the type that would be obtained from evaluating an expression if it were not for the effects of integral promotion.

The line signed long int test = -1; is MISRA-C:2004 (and MISRA-C:2012) compliant.

  • The expression -1 contains no implicit promotions in itself. Integral promotion does not apply.
  • Thus -1 has underlying type signed int and upon assignment, it is implicitly converted to a wider integer type with the same signedness, which is fine.
  • The intention is to create a signed variable, so the rule about u suffix does not apply.
  • Furthermore, the rule 10.1 against implicit conversions from a so-called "complex expression" into different a type does not apply either, since -1 is a constant expression, not a complex expression (see MISRA-C:2004 6.10.5).

So this is yet another tool bug. The tool seems to picking the wrong underlying type of an expression, which would be a severe bug.

signed long int test = -1L; is not necessary for compliance, although it is also compliant code.

Related