Does INT_MIN % -1 produce undefined behavior?

牧云@^-^@ 提交于 2019-12-21 03:13:20

问题


gcc generates floating code that raises SIGFPE for the following code:

#include <limits.h>
int x = -1;
int main()
{
    return INT_MIN % x;
}

However I can find no statement in the standard that this code invokes undefined or implementation-defined behavior. As far as I can tell, it's required to return 0. Is this a bug in gcc or am I missing some special exception the standard makes?


回答1:


You are probably right that this can be considered as a bug in the actual standard. The current draft addresses this problem:

If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a; otherwise, the behavior of both a/b and a%b is undefined.




回答2:


Looking at the assembly code generated by gcc (x is defined as -1 earlier in the assembly):

movl    x, %ecx
movl    $-2147483648, %eax
movl    %eax, %edx
sarl    $31, %edx
idivl   %ecx

The first computational instruction, sarl, right shifts -2147483648 31 bits. This results in -1 which is put in %edx.

Next idivl is executed. This is a signed operation. Let me quote the description:

Divides the contents of the double-word contained in the combined %edx:%eax registers by the value in the register or memory location specified.

So -1:-2147483648 / -1 is the division that happens. -1:-2147483648 interpreted as a double word equals -2147483648 (on a two's complement machine). Now -2147483648 / -1 happens which returns 2147483648. BOOM! That's one more then INT_MAX.


About the why question, is this a bug in gcc or am I missing some special exception the standard makes?

In the C99 standard this is implicit UB (§6.5.5/6):

…the result of the / operator is the algebraic quotient with any fractional part discarded.88) If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.

INT_MIN / -1 cannot be represented, thus this is UB.

In C89 however the % operator is implementation defined and whether this is a compiler bug or not can be debated. The issue is listed at gcc however: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30484




回答3:


It's the CPU's fault.




回答4:


The same question is asked here as a Defect Report

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#614

Unfortunately I don't see it stated explicitly in the resolution part that it should produce UB. The division would indeed produce UB, but for the % operator it is not obvious.




回答5:


The result of the modulus operation with negative operands is left implementation-defined in C89, and defined in C99 by §6.5.5/6:

…the result of the / operator is the algebraic quotient with any fractional part discarded.88) If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.

88) This is often called "truncation toward zero".

For a two's-complement representation, INT_MIN / -1 is equal to INT_MAX + 1, so it's not representable as an int without wrapping, and I guess the implementation elects to leave it explosive.



来源:https://stackoverflow.com/questions/5925045/does-int-min-1-produce-undefined-behavior

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