C integer overflow

无人久伴 提交于 2019-12-25 16:07:07

问题


I was working with integers in C, trying to explore more on when and how overflow happens.

I noticed that when I added two positive numbers, the sum of which overflows, I always got a negative number.

On the other hand, if I added two negative numbers, the sum of which overflows, I always got a positive number (including 0).

I made few experiments, but I would like to know if this is true for every case.


回答1:


Integer overflows are undefined behavior in C.

C says an expression involving integers overflows, if its result after the usual arithmetic conversions is of a signed typed and cannot be represented in the type of the result. Assignment and cast expressions are an exception as they are ruled by the integer conversions.

Expressions of unsigned type cannot overflow, they wrap, e. g., 0U - 1 is UINT_MAX.

Examples:

INT_MAX + 1    // integer overflow
UINT_MAX + 1   // no overflow, the resulting type is unsigned
(unsigned char) INT_MAX // no overflow, integer conversion occurs 

Never let any integer expression overlflows, modern compilers (like gcc) take advantage of integer overflows being undefined behavior to perform various types of optimizations.

For example:

a - 10 < 20

when a is of type int after promotion, the expression is reduced in gcc (when optimization are enabled) to:

a < 30

It takes advantage of the expression being undefined behavior when a is in the range INT_MIN + 10 - 1 to INT_MIN.

This optimization could not be done when a is unsigned int because if a is 0, then a - 10 has to be evaluated as UINT_MAX - 9 (no undefined behavior). Optimizing a - 10 < 20 to a < 30 would then lead to a different result than the required one when a is 0 to 9.




回答2:


Overflow of signed integers is undefined behaviour in C, so there are no guarantees.

That said, wrap around, or arithmetic modulo 2N, where N is the number of bits in the type, is a common behaviour. For that behaviour, indeed if a sum overflows, the result has the opposite sign of the operands.




回答3:


Formally, the behaviour of signed arithmetic on overflow is undefined; anything can happen and it is 'correct'. This contrasts with unsigned arithmetic, where overflow is completely defined.

In practice, many older compilers used signed arithmetic which overflowed as you describe. However, modern GCC is making changes to the way it works, and you'd be very ill-advised to rely on the behaviour. It may change at any time when anything in the environment where your code is compiled changes — the compiler, the platform, ...



来源:https://stackoverflow.com/questions/12335784/c-integer-overflow

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