不同Provenance的指针能否相等?该GCC行为是否符合C标准?
GCC中不同Provenance指针相等是否符合C标准?
测试代码与运行结果
测试代码(test.c)
// test.c #include <stdio.h> int a[4]; int b[4]; int main() { puts(a+4 == b ? "equal" : "inequal"); return 0; }
编译运行输出
$ gcc --version gcc (GCC) 13.2.1 20230801 $ gcc test.c && ./a.out equal
行为是否符合C标准?
这个行为符合C标准,具体依据如下:
根据C标准(以C17为例,条款6.5.9 相等运算符)的规定,两个指针比较相等的合法场景包括:
- 两者均为空指针;
- 两者指向同一个对象(含对象起始位置的子对象);
- 两者指向同一个数组对象的最后一个元素的下一个位置;
- 其中一个指针指向某数组的末尾后一个位置(one past pointer),另一个指针指向另一数组的起始位置,且这两个数组在地址空间中恰好紧挨着。
在这个测试案例中,全局数组a和b被GCC安排在内存中相邻位置,a+4是数组a的末尾后一个位置,b是紧随其后的数组b的起始地址,正好满足上述最后一种合法的指针相等场景。
需要注意的是,这种结果依赖于编译器的内存布局策略,并非所有编译环境都会将两个全局数组放在相邻位置,因此代码输出是实现相关的,但完全符合C标准规定——标准允许这种情况下的指针相等,并未将其判定为未定义行为。
内容的提问来源于stack exchange,提问作者Sylvain Hubert
相关产品推荐
相关产品推荐

