我碰到了这篇帖子https://stefansf.de/post/pointers-are-more-abstract-than-you-might-expect/,其中提到
C11§6.5.9第6段当且仅当两个指针均相等时,两个指针比较相等 是空指针,都是指向同一对象的指针(包括 指向对象及其子对象开头的指针)或函数, 两者都是指向同一数组的最后一个元素的指针 对象,或者是一个指向一个数组对象末尾的指针 另一个是指向另一个数组对象开始的指针 恰好紧跟在 地址空间。
为什么在此程序中可以在b
之后立即访问a
,尽管地址的打印输出相同,但&a+1
却不等于&b
的原因< / p>
#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);
}
这让我怀疑,这不可能跨越不可倾斜的功能边界(或转换单元边界或DSO边界)来维持,所以我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);
}
的确,这让我
0x7ffc38b8ec5c != 0x7ffc38b8ec5c
1 2
0x7ffc38b8ec5c == 0x7ffc38b8ec5c
10 20
使用gcc(6.4),甚至
0x7ffe5d0cee6c == 0x7ffe5d0cee6c
2 1
0x7ffe5d0cee6c == 0x7ffe5d0cee6c
20 10
带有lang声(3.4)。
我的问题是,6.5.9p6规则是否有意义?似乎不可能有效地跟踪类似内容。