[Bug c/39121] strange behavior in chained operations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39121 joe.carnuccio at qlogic dot com changed: What|Removed |Added CC||joe.carnuccio at qlogic dot com --- Comment #4 from joe.carnuccio at qlogic dot com --- I have found the following: This works: c ^= d ^= c ^= d (where c and d are not pointers) This fails: *a ^= *b ^= *a ^= *b (where a and b are pointers) When compiling using -Os then the failed case now works.
[Bug c/39121] strange behavior in chained operations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39121 --- Comment #5 from joe.carnuccio at qlogic dot com --- Since using gcc -Os causes the correct execution, then "sequence point" does not have anything to do with it.
[Bug c/66673] New: swapping variables via chained xor fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66673 Bug ID: 66673 Summary: swapping variables via chained xor fails Product: gcc Version: 4.4.6 Status: UNCONFIRMED Severity: major Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: joe.carnuccio at qlogic dot com Target Milestone: --- This is the same as 39121 which has been marked RESOLVED INVALID (to which I strongly disagree): this produces incorrect executable: *p ^= *q ^= *p ^= *q; ( if gcc option "-Os" is used, then that produces correct executable ) ( by contrast, this always produces correct executable: a ^= b ^= a ^= b; ) root@elab305:/home/joe/test/c# cat x.c #include int main(int argc, char **argv) { int a = 0x32, b = 0x45; int *p = &a, *q = &b; *p ^= *q ^= *p ^= *q; printf("%x %x\n", a, b); return 0; } root@elab305:/home/joe/test/c# make -B x cc-c -o x.o x.c cc x.o -o x root@elab305:/home/joe/test/c# ./x 0 32 <--INCORRECT root@elab305:/home/joe/test/c# make -B x CFLAGS+='-Os' cc -Os -c -o x.o x.c cc x.o -o x root@elab305:/home/joe/test/c# ./x 45 32 <--CORRECT root@elab305:/home/joe/test/c# Notice that when -Os (optimize for space rather than speed) is used, the executable produces the correct result. Also, doing the chained xor on the integer variables a and b themselves always produces the correct result (regardless of optimization). root@elab305:/home/joe/test/c# gcc --version gcc (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3) . . . root@elab305:/home/joe/test/c# uname -a Linux elab305 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux root@elab305:/home/joe/test/c# cat /etc/issue Red Hat Enterprise Linux Server release 6.2 (Santiago) Kernel \r on an \m
[Bug c/66673] swapping variables via chained xor fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66673 --- Comment #2 from joe.carnuccio at qlogic dot com --- -Wall produces no warnings... root@elab305:/home/joe/test/c# make -B x -Wall cc-c -o x.o x.c cc x.o -o x root@elab305:/home/joe/test/c# ./x 0 32
[Bug c/66673] swapping variables via chained xor fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66673 --- Comment #3 from joe.carnuccio at qlogic dot com --- Sorry, I ment this: root@elab305:/home/joe/test/c# make -B x CFLAGS+='-Wall' cc -Wall -c -o x.o x.c cc x.o -o x root@elab305:/home/joe/test/c# ./x 0 32
[Bug c/39121] strange behavior in chained operations
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39121 --- Comment #7 from joe.carnuccio at qlogic dot com --- Ok, the sequence points are at each of the assignment operators. The crux of this is that doing the xor chain with dereferenced pointers fails (incorrect execution), whereas doing it with variables works... i.e. *a and *b are being treated differently than a and b; a ^= b ^= a ^= b is supposed to do the following: a = a ^ (b = b ^ (a = a ^ b)) from right-to-left each assignment is done in sequence (and has been verified to work correctly); *a ^= *b ^= *a ^= *b should work the same way, but it does not (unless you compile with -Os).
[Bug c/66673] swapping variables via chained xor fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66673 --- Comment #4 from joe.carnuccio at qlogic dot com --- if I do a ^= b ^= a ^= b it always work correctly; doing *p ^= *q ^= *p ^= *q fails (unless -Os is used); i.e. dereferenced pointers are being treated differently int a = 0x32, b = 0x45; int *p = &a, *q = &b;