比较指向不同数组的指针(如pa、pb)是否属于定义行为?
关于C语言跨数组指针比较的定义行为问题
嘿,这是个C语言里很容易踩坑的细节问题,咱们掰开了说:
1. 指向不同数组的两个指针做相等性比较(== / !=)是定义行为吗?
答案是:除非满足特定条件,否则属于未定义行为。
C标准里明确规定,只有以下几种情况的指针相等性比较是定义良好的:
- 两个指针都是空指针(比如
NULL); - 两个指针指向同一个对象(包括同一个数组的同一个元素);
- 两个指针都指向同一个数组的「尾后指针」位置(比如
&arr[arr_length],这个指针不指向数组元素,但属于数组的合法指针范围)。
如果两个指针分别指向完全独立的两个数组对象,那直接用==或!=比较的结果是未定义的——编译器可以随便输出真/假,甚至触发奇怪的行为,完全没有保证。举个反例:
int foo[3]; int bar[3]; int *p_foo = foo; int *p_bar = bar; // 这里的比较是未定义行为,结果不可靠 if (p_foo == p_bar) { // 别指望这段代码有稳定表现 }
2. 当pa和pb都不指向同一数组的元素时,这类比较操作是否良好定义?
这里得分相等性比较和**关系性比较(<、>、<=、>=)**两种情况说:
- 相等性比较:只有当两个指针是空指针,或者其中一个/两个指向某个对象的尾后位置(且符合之前说的合法场景)时,才是定义良好的。如果是指向完全无关的对象(比如两个不同的非数组对象,或者不同数组的元素),那还是未定义行为。
- 关系性比较:只要两个指针不是指向同一个数组的元素(包括该数组的尾后指针),这类比较全都是未定义行为。哪怕你觉得两个数组在内存里是相邻的,也绝对不能假设
p_foo < p_bar这种比较有意义——编译器完全可能打乱内存布局,或者优化出你意料之外的结果。
总结一下:跨数组的指针比较,除了空指针的情况,其他场景都别碰,绝对属于C语言里的「危险操作」。
内容的提问来源于stack exchange,提问作者Bathsheba
相关产品推荐
相关产品推荐

