Does INT_MIN % -1 produce undefined behavior?
Looking at the assembly code generated by gcc (x is defined as -1 earlier in the assembly):
movl x, %ecxmovl $-2147483648, %eaxmovl %eax, %edxsarl $31, %edxidivl %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