具有不同起源的指针在最近的gcc版本中可以是相等的:
// test.c #include <stdio.h> int a[4]; int b[4]; int main() { puts(a+4 == b ? "equal" : "inequal"); return 0; }
个字符这种行为符合c标准吗?
nuypyhwy1#
这是允许发生的,但不能保证。C standard的第6.5.9p6节关于相等运算符的规定:
两个指针比较相等当且仅当都是空指针,都是指向同一个对象的指针(包括指向对象的指针和在其开头的子对象)或函数,两者都是指向同一数组对象的最后一个元素的指针,或者一个是指向一个数组对象末尾之后的指针,另一个是指向恰好紧随其后的另一个数组对象的开始的指针地址空间中的第一个数组对象。109)
...1.两个对象可能在内存中相邻,因为它们是较大数组的相邻元素或结构的相邻成员,它们之间没有填充,**或者因为实现选择将它们放置在这样的位置,即使它们不相关。**如果先前的无效指针操作(如数组边界外的访问)产生未定义的行为,则随后的比较也会产生未定义的行为一些编译器可能知道指针的出处,并可以使用该知识来决定这种比较是否正确。标签:Can an equality comparison of unrelated pointers evaluate to true?
eivgtgni2#
这种行为符合c标准吗?指针值的出处在某些情况下确实很重要,但C语言并不要求或保证出处无关的指针必须比较不相等。相反,它说:两个指针比较相等当且仅当两个指针都是空指针,都指向同一个对象(包括指向对象的指针和在其开头的子对象)或函数,两者都是指向同一数组对象的最后一个元素的指针,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象开头的指针,地址空间中第一个数组对象的后面。(C17 6.5.9/6;着重号由作者标明)它澄清说:两个对象可能在内存中相邻,因为它们是一个较大数组的相邻元素或一个结构的相邻成员,它们之间没有填充,或者因为实现选择这样放置它们,即使它们不相关。(C17脚注111)
2条答案
按热度按时间nuypyhwy1#
这是允许发生的,但不能保证。
C standard的第6.5.9p6节关于相等运算符的规定:
两个指针比较相等当且仅当都是空指针,都是指向同一个对象的指针(包括指向对象的指针和在其开头的子对象)或函数,两者都是指向同一数组对象的最后一个元素的指针,或者一个是指向一个数组对象末尾之后的指针,另一个是指向恰好紧随其后的另一个数组对象的开始的指针地址空间中的第一个数组对象。109)
...
1.两个对象可能在内存中相邻,因为它们是较大数组的相邻元素或结构的相邻成员,它们之间没有填充,**或者因为实现选择将它们放置在这样的位置,即使它们不相关。**如果先前的无效指针操作(如数组边界外的访问)产生未定义的行为,则随后的比较也会产生未定义的行为
一些编译器可能知道指针的出处,并可以使用该知识来决定这种比较是否正确。
标签:Can an equality comparison of unrelated pointers evaluate to true?
eivgtgni2#
这种行为符合c标准吗?
指针值的出处在某些情况下确实很重要,但C语言并不要求或保证出处无关的指针必须比较不相等。相反,它说:
两个指针比较相等当且仅当两个指针都是空指针,都指向同一个对象(包括指向对象的指针和在其开头的子对象)或函数,两者都是指向同一数组对象的最后一个元素的指针,或者一个是指向一个数组对象末尾的指针,另一个是指向另一个数组对象开头的指针,地址空间中第一个数组对象的后面。
(C17 6.5.9/6;着重号由作者标明)
它澄清说:
两个对象可能在内存中相邻,因为它们是一个较大数组的相邻元素或一个结构的相邻成员,它们之间没有填充,或者因为实现选择这样放置它们,即使它们不相关。
(C17脚注111)