Summary: | optimisation bug with -0x80000000 | ||
---|---|---|---|
Product: | gcc | Reporter: | Simon Marlow <simonmar> |
Component: | c | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED DUPLICATE | ||
Severity: | major | CC: | gcc-bugs, simonmar |
Priority: | P3 | ||
Version: | 4.1.0 | ||
Target Milestone: | --- | ||
Host: | x86_64-redhat-linux | Target: | x86_64-redhat-linux |
Build: | x86_64-redhat-linux | Known to work: | |
Known to fail: | Last reconfirmed: |
Description
Simon Marlow
2006-03-23 11:37:22 UTC
-0x80000000 is going to overflow and for signed integers overflow is undefined. If you want signed integers to be defined to be wrapping use -fwrapv. Wait a minute. 0x80000000 is unsigned. So -0x80000000 is well-defined, and is 0x80000000 (unsigned). This is then converted to signed. Since 0x80000000 cannot be represented in signed, the result is implementation specific. We document it to be -0x80000000. So the call is just fine. It is the -x in f where x = 0x80000000 which is undefined as it overflows. (In reply to comment #3) > It is the -x in f where x = 0x80000000 which is undefined as it overflows. Oh. I see. Right. I see your point, but I still think there's a bug. Let me change the code slightly: #include <stdlib.h> #include <stdio.h> void f(int x) { long y; if (x < 0) { y = -x; if (y > 0) { printf("%d\n",y); } } } int main() { f(-0x80000000); exit(0); } $ gcc -O2 foo.c $ ./a.out -2147483648 so, we're in the y > 0 branch, but y is clearly < 0. Pinskia is right, and this is just as undefined as your previous example (negating INT_MIN is just undefined, however you do it). All you've done is obfuscated things a bit more. (In reply to comment #5) > I see your point, but I still think there's a bug. Let me change the code > slightly: The code is still undefined, as you are comparing an overflowed variable to something. -x is still undefined for x being 0x80000000 as it overflows and overflow signed integer is undefined runtime code. Reopening to ... |