Search code examples
cmisra

Wraparound in unsigned arithmetic operation


The following MISRA violations appeared while analyzing the following code:

#define z  (USHORT)14745

#define Convert(x) ((((USHORT)x*(unsigned short)1000) + ((z) / (USHORT)2)) /(z))

static const USHORT array [2] = 

{
   Convert(176), -> Line "1"
   Convert(206)  -> Line "2"
};

The following MISRA violations are detected on both lines "1", "2":

  • Integral promotion : unsigned short promoted to unsigned int. REFERENCE - ISO:C90-6.2.1.1 Characters and Integers

  • Constant: Wraparound in unsigned arithmetic operation. MISRA-C:2004 Rule 12.11; REFERENCE - ISO:C90-6.1.2.5 Types

  • The result of this cast is implicitly converted to another type.

My question is: Why there will be a wraparound in this operation ?!

Note: When I am checking the values of array with debugger:

array [2] = 
{
  12,
  14
} 

which are the correct values.


Solution

  • It is related to Integral Promotion:

    Integer types smaller than int are promoted when an operation is performed on them. If all values of the original type can be represented as an int, the value of the smaller type is converted to an int; otherwise, it is converted to an unsigned int.

    So that, the macro Convert(206) [((((unsigned short)206*(unsigned short)1000) + ((z) / (USHORT)2)) /(z))] will be executed as following:

    1. "206" will be promoted to signed int.
    2. "1000" will be promoted to signed int.
    3. The operation "206 * 1000" will be performed and the result will be of type signed int also -> "206000".
    4. z, 2 will be promoted to signed int.
    5. The operation z / 2 will be performed and the result will be of type signed int -> "14745 / 2" = "7372" 6."206000" + "7372" will be performed and the result will be of type signed int -> 213372
    6. "213372" will be divided by "14745" resulting "14"