为何C++中两地址互不小于却不相等?地址比较异常解析
局部变量指针比较的诡异行为解析
问题场景
在Windows 11系统下,使用Embarcadero C搭配GNU G17编译运行以下代码:
#include<bits/stdc++.h> using namespace std; int main(){ int a,b; cout<<&a+1<<endl<<&b<<endl; cout<<(&a+1==&b)<<endl; return 0; }
运行输出:
0x78fe1c 0x78fe1c 0
原本预期地址数值相同的&a+1和&b,==比较应返回1,但实际返回0。为排查问题补充代码:
#include<bits/stdc++.h> using namespace std; int main(){ int a,b; cout<<&a+1<<endl<<&b<<endl; cout<<(&a+1<=&b)<<endl; cout<<(&a+1>=&b)<<endl; cout<<(&a+1==&b)<<endl; cout<<(&a+1!=&b)<<endl; return 0; }
输出结果更矛盾:
0x78fe1c 0x78fe1c 1 1 0 1
即&a+1既不大于也不小于&b,却又不相等。
根本原因
这是典型的C++指针比较的未定义行为,具体原因如下:
- C++标准明确规定,只有当两个指针指向同一个数组的元素(含数组末尾后一个位置),或者指向同一个对象/其子对象时,指针的比较(
==、<、>等)操作才是有定义的。 - 这里
a和b是两个独立的局部变量,不属于同一个数组或对象。&a+1是指向a之后一个int大小位置的指针,即便其数值恰好等于&b的地址,这两个指针也不满足标准中允许比较的前提条件。 - 未定义行为意味着编译器可以自由处理这种情况,可能出现逻辑矛盾的结果(比如同时满足
<=和>=却不满足==),这是因为编译器优化、指针底层表示的特殊处理等因素导致的,结果完全不可预测。
总结
不要对非同一数组/对象的指针进行比较操作,这类操作的结果不受C++标准保障,出现任何诡异现象都属于正常的未定义行为范畴。
内容的提问来源于stack exchange,提问作者cppHusky
相关产品推荐
相关产品推荐

