不同出处的指针可以相等吗?

问题描述 投票:0回答:2

在最新版本的 gcc 中,具有不同出处的指针可以相等:

// 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 pointers
2个回答
0
投票

这个行为符合c标准吗?

在某些情况下,指针值的出处确实很重要,但 C 语言不要求或保证出处不相关的指针必须比较不相等。相反,它说:

两个指针比较相等当且仅当两者都是空指针, 是指向同一个对象的指针(包括指向对象的指针和 开头的子对象)或函数,两者都是指向一个的指针 超过同一数组对象的最后一个元素,或者其中一个是指针 一个指向一个数组对象的末尾,另一个是指向 立即发生的不同数组对象的开始 跟随地址空间中的第一个数组对象。

(C17 6.5.9/6;已添加强调)

澄清:

两个对象在内存中可能是相邻的,因为它们是相邻的 较大数组的元素或结构的相邻成员,没有 它们之间的填充,或者因为实现选择放置 他们是如此,即使他们无关。

(C17脚注111)


0
投票

这是允许发生的,但不能保证。

C 标准第 6.5.9p6 节有关相等运算符的规定:

两个指针比较相等当且仅当两者都是空指针, 是指向同一个对象的指针(包括指向对象的指针和 开头的子对象)或函数,两者都是指向一个的指针 超过同一数组对象的最后一个元素,或者其中一个是指向 一个超过一个数组对象的末尾,另一个是指向 紧随其后的另一个数组对象的开始 地址空间中的第一个数组对象。109)

...

  1. 两个对象在内存中可能相邻,因为它们是较大数组的相邻元素或 结构的相邻成员之间没有填充,或者因为实现选择 即使它们不相关,也可以这样放置它们。 如果先前的无效指针操作(例如访问 数组边界之外)产生未定义的行为,后续比较也会产生未定义的结果 行为
一些编译器可能了解指针的出处,并可以使用该知识来决定这种比较是否正确。

© www.soinside.com 2019 - 2024. All rights reserved.