简体   繁体   中英

MISRA Error due to Wraparound of unsigned arithmetic operator

I am having an issue for MISRA standards regarding wraparound error. I have tried to resolve it by having a look at options available on internet but remained unable to resolve it as remained unable to find some viable solution.

I am providing a simple example to explain my situation.

I am having a wraparound error in result line due to MISRA standards. Wraparound in unsigned arithmetic operation.

Can someone provide me a reason why it is happening and how to cater this situation.

Thanks a lot.

 unsigned int x;
 unsigned int y;
 unsigned int z;
 unsigned int result;

 x= 0;
 y = 60;
 z = 60;

 result = x-y +z;

As Dietrich Epp remarked correctly, the code analyzer observes that for the given values — which are known and visible at compile time — the sub-expression xy will mathematically be negative. Negative values are out of the value range of unsigned types, they cannot be represented; such a situation is called an overflow . It is well-defined for unsigned integers in C++ (6.7.1/4 plus footnote 45 in the standard draft n4713 ) and in C (6.2.5/9 in the standard draft n1256 ): "Unsigned integers shall obey the laws of arithmetic modulo 2 n where n is the number of bits in the value representation."

Modulo arithmetic "wraps around". One can image the possible values as a circle where the maximum (all bits set) and minimum (no bit set) values are adjacent . Like with all other adjacent values I can go from one to the other by adding or subtracting 1: ((uint8_t)0xff+1 == 0 , and correspondingly ((uint8_t)0-1 == 0xff . (The bit pattern 0xff... to represent -1 in the usual 2-complement is known to most programmers, but it may still come as a surprise when it results from a computation.) In a 2-complement representation this transition comes naturally because 0xfff... +1 is 0x10000... , with the carry bit, the leading 1, "to the left" of the bits in the machine representation; it is simply thrown away.

The bottom line is: Perhaps surprisingly a small negative value like -60 assigned to an unsigned int results in a large number. This is what MISRA alerts you of.

In your particular case, with the values given, there is no issue because in modulo arithmetic addition is still the inverse operation to subtraction no matter the values so that 0-60+60 is 0. But problems may arise if z is, say, 58, so the result is -2; this would result in the second-highest value assigned to result which its type can hold. That may have disastrous consequences if eg the value is used to terminate a for loop. With signed integers the loop would be skipped; with unsigned integers it will, probably wrongly, run for a long time.

After clarifying the underlying issue the following questions arise:

  1. As demonstrated the computation is well defined with unsigned operands and, with the given arguments, has an unsurprising result. Are you happy with all results which can occur with all possible argument values and combinations — that is, are you are happy with modulo arithmetic?

    1a. Yes: Then the question is whether you want or must prevent the warning. Technically, there is nothing to do. Any change would likely obscure matters. Apparently, MISRA warnings can be suppressed .

    1b. If that is not possible or desired your software development process will likely have a mechanism to qualify such warnings as acceptable.

    1c. If that is not possible or desired you'll have to (unnecessarily) complicate your code. One solution is to simply perform the computation with 64 bit signed integers which are guaranteed to be able to hold all 32 bit unsigned values (assuming that sizeof int == 32 on your system), and assign the result with an explicit cast to indicate that the possible overflow and loss of information is intentional.

    Or, if in your data y < z && x + z < UINT_MAX always holds, you can simply re-order the evaluation to result = x + z - y; , never encountering negative values in sub-expressions.

  2. If you are unhappy with modulo arithmetic, especially with the possibility of unexpectedly large results, you have to step back and reconsider the data model you are using for your real-world data. Maybe you must qualify your data and prevent negative outcomes, or you must use signed integers, or something else is amiss.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM