I came across this post https://stefansf.de/post/pointers-are-more-abstract-than-you-might-expect/ which mentions
C11 § 6.5.9 paragraph 6 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.
as rationalization for why in this program may address b
right after a
and yet have &a+1
compare unequal to &b
even though the printouts of the addresses are indentical
#include <stdio.h>
int main(void) {
int a, b; int *p = &b; int *q = &a + 1;
printf("%p %p %d\n", (void *)p, (void *)q, p == q);
}
This made me wonder that this cannot possibly be maintained across noninlinable function boundaries (or translation unit boundaries or DSO boundaries) so I tried:
#include <stdio.h>
#pragma GCC optimize "O2"
void addrcmp(void *a1_p, void *b_p)
{
printf("%p %c= %p\n", a1_p,"!="[a1_p==b_p],b_p);
int *a1p = a1_p;
int *bp = b_p;
a1p[-1] *= 10;
bp[0] *= 10;
}
int main()
{
#if __clang__ /*clang appears to lay the variables in reverse order*/
int b=1, a=2;
#else
int a=1, b=2;
#endif
printf("%p %c= %p\n", (void*)(&a+1),"!="[&a+1==&b],(void*)&b);
printf("%d %d\n", a, b);
addrcmp(&a+1,&b);
printf("%d %d\n", a, b);
}
and indeed, this is getting me
0x7ffc38b8ec5c != 0x7ffc38b8ec5c
1 2
0x7ffc38b8ec5c == 0x7ffc38b8ec5c
10 20
with gcc (6.4), and even
0x7ffe5d0cee6c == 0x7ffe5d0cee6c
2 1
0x7ffe5d0cee6c == 0x7ffe5d0cee6c
20 10
with clang (3.4).
My question is, does the 6.5.9p6 rule even make sense? It seems impossible to track something like that efficiently.