"gcc --version" says gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2 "uname -a" says Linux bomb20 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux (The system is Linux Mint 17, based on Ubuntu 14.04.1 LTS.) I've created a Gist at https://gist.github.com/Keith-S-Thompson/60dc069f4823fb1c3209 but of course I'll include the information here. The C standard's definition of "==" for pointers (N1570 6.5.9 paragraph 6) says: Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space. which implies that the test program below should print (among other output) one of the following: - "y immediately follows x" followed by "ok"; - "x immediately follows y" followed by "ok"; or - "x and y are not adjacent" Instead, when compiled with gcc, it prints "inconsistent behavior: ...". It appears that gcc is assuming that a pointer just past the end of one declared object cannot be equal to a pointer to the beginning of another object, when the two objects are not subobjects of the same containing object. Examining an assembly listing indicates that the code to print "ok" is not even generated, implying that this is an optimization bug (that occurs even at "-O0". I don't expect that this is a common use case, but the compiled program does behave in a manner inconsistent with the standard's requirements. I see the same behavior with a copy of gcc 4.9.1 built from source on the same system. (I also see it with clang 3.5-1ubuntu1, but with the order of x and y reversed; that's not directly relevant to this bug report, but it's mildly interesting.) The command line used to compile and execute the program is: $ gcc -std=c11 -pedantic -Wall -Wextra pointer_equality_bug.c -o pointer_equality_bug && ./pointer_equality_bug The output on my system is: x = 0x7fff2a94a1d0 x0 = 0x7fff2a94a1d0 x1 = 0x7fff2a94a250 y = 0x7fff2a94a250 y0 = 0x7fff2a94a250 y1 = 0x7fff2a94a2d0 y immediately follows x inconsistent behavior: 0x7fff2a94a250 != 0x7fff2a94a250 And the program itself (73 lines, making up the remainder of this description) is: #include <stdio.h> #include <stdlib.h> int main(void) { typedef struct { int arr[32]; } element; element x[1]; element y[1]; element *const x0 = x; element *const x1 = x0 + 1; element *const y0 = y; element *const y1 = y0 + 1; /* * x and y will typically be adjacent in memory. * x0 points to x; x1 points just past it. * y0 points to y; y1 points just past it. * We should have x1 == y0 if and only if y immediately follows x. * We should have y1 == x0 if and only if x immediately follows y. */ printf("x = %p\nx0 = %p\nx1 = %p\ny = %p\ny0 = %p\ny1 = %p\n", (void*)x, (void*)x0, (void*)x1, (void*)y, (void*)y0, (void*)y1); if (x1 == y0) { puts("y immediately follows x"); if (x + 1 == y) { puts("ok"); } else if (x + 1 != y) { printf("inconsistent behavior:\n" " %p !=\n" " %p\n", (void*)(x + 1), (void*)y); exit(EXIT_FAILURE); } else { printf("inconsistent behavior:\n" " %p !=\n" " %p\n", (void*)(x + 1), (void*)y); exit(EXIT_FAILURE); } } else if (y1 == x0) { puts("x immediately follows y"); if (y + 1 == x) { puts("ok"); } else if (y + 1 != x) { printf("inconsistent behavior:\n" " %p !=\n" " %p\n", (void*)(y + 1), (void*)x); exit(EXIT_FAILURE); } else { printf("inconsistent behavior:\n" " %p !=\n" " %p\n", (void*)(y + 1), (void*)x); exit(EXIT_FAILURE); } } else { puts("x and y are not adjacent"); } }
A bug report for a similar issue with clang is here: http://llvm.org/bugs/show_bug.cgi?id=21327
See bug 61502. The last comment there appears to indicate a bug, but the test given here doesn't based on my understanding that whether two objects follow each other need not be constant for all comparisons. *** This bug has been marked as a duplicate of bug 61502 ***