What happens when a integer overflow occurs in a C expression?

牧云@^-^@ 提交于 2019-12-10 16:52:33

问题


I have the following C code:

uint8_t firstValue = 111;
uint8_t secondValue = 145;
uint16_t temp = firstValue + secondValue;
if (temp > 0xFF) {
    return true;
}
return false;

This is the alternative implementation:

uint8_t firstValue = 111;
uint8_t secondValue = 145;
if (firstValue + secondValue > 0xFF) {
    return true;
}
return false;

The first example is obvious, the uint16_t type is big enough to contain the result. When I tried the second example with the clang compiler on OS/X, it correctly returned true. What happens there? Is there some sort of temporary, bigger type to contain the result?


回答1:


The operands of + are promoted to larger types, we can see this by going to draft C99 standard section 6.5.6 Additive operators which says:

If both operands have arithmetic type, the usual arithmetic conversions are performed on them.

and if we go to 6.3.1.8 Usual arithmetic conversions it says:

Otherwise, the integer promotions are performed on both operands.

and then we go to 6.3.1.1 Boolean, characters, and integers which says (emphasis mine):

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.48) All other types are unchanged by the integer promotions.

So both operands of + in this case will be promoted to type int for the operation, so there is no overflow.

Note, Why must a short be converted to an int before arithmetic operations in C and C++? explains the rationale for promotions.




回答2:


The first example is obvious, the uint16_t type is big enough to contain the result.

In fact the destination lvalue x for the assignment x = expr; has no bearing on whether there is an overflow in expr. If there is, then the result is what it is regardless of how wide x is.

In your example, “integer promotions” apply and the computation is done between int operands. This means that there is no overflow. Integer promotions are described in C11 in clause 6.3.1.1:2.

If you had been adding two uint32_t values, then there could have been wrap-around (the specified behavior when an unsigned operation produces a result that is out of bounds for the unsigned type), even if the type of the lvalue to assign to result to was uint64_t.




回答3:


Yes, all arithmetic is done in a type that has at least the width of int. So your operands are first converted to int and then the operation is performed. As in your first example, the result is then converted back to the target type of the assignment.

Usually it is not a good idea at all to do arithmetic with narrow types. Avoid that when you can, it only complicates things. Best is to avoid these types completely, unless you have a real problem to store large arrays of numbers, e.g.




回答4:


In C, intermediate results are done as at least int, wider if the input type is long or some larger datatype.



来源:https://stackoverflow.com/questions/26195811/what-happens-when-a-integer-overflow-occurs-in-a-c-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!