在最新版本的 gcc 中,具有不同来源的指针可以是相等的:
// test.c
#include <stdio.h>
int a[4];
int b[4];
int main() {
puts(a+4 == b ? "equal" : "inequal");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
$ gcc --version
gcc (GCC) 13.2.1 20230801
$ gcc test.c && ./a.out
equal
Run Code Online (Sandbox Code Playgroud)
这种行为符合c标准吗?
dbu*_*ush 11
这是允许发生的,但不能保证。
C 标准第 6.5.9p6 节有关相等运算符的规定:
两个指针比较相等当且仅当两个指针都是空指针,两个都是指向同一个对象(包括指向对象的指针和其开头的子对象)或函数的指针,两个指针都是指向同一数组的最后一个元素之后的指针对象,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象的开头的指针,该数组对象恰好紧随地址空间中的第一个数组对象。109)
...
- 两个对象在内存中可能是相邻的,因为它们是较大数组的相邻元素或结构的相邻成员,它们之间没有填充,或者因为实现选择这样放置它们,即使它们不相关。如果先前的无效指针操作(例如访问数组边界之外)产生未定义的行为,则后续比较也会产生未定义的行为
一些编译器可能了解指针来源,并可以使用该知识来确定这种比较是否正确。
这种行为符合c标准吗?
在某些情况下,指针值的出处确实很重要,但 C 语言不要求或保证出处不相关的指针必须比较不相等。相反,它说:
两个指针比较相等当且仅当两个指针都是空指针,两个都是指向同一个对象(包括指向对象的指针和其开头的子对象)或函数的指针,两个指针都是指向同一数组的最后一个元素之后的指针对象,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象的开头的指针,该数组对象恰好紧随地址空间中的第一个数组对象。
(C17 6.5.9/6;添加强调)
它澄清:
两个对象在内存中可能是相邻的,因为它们是较大数组的相邻元素或结构的相邻成员,它们之间没有填充,或者因为实现选择这样放置它们,即使它们不相关。
(C17脚注111)
| 归档时间: |
|
| 查看次数: |
162 次 |
| 最近记录: |