这个程序合法吗?如果是这样,请参考其中一种语言标准来支持您的主张(无论哪种方式)。
void f(char *p) {
char *q = p - 1;
(void)( q < p );
};
int main(void) {
char arr[] = "Hello";
f( arr );
}
特别是,我对q < p
比较是否合法感兴趣。
这个程序合法吗?如果是这样,请参考其中一种语言标准来支持您的主张(无论哪种方式)。
void f(char *p) {
char *q = p - 1;
(void)( q < p );
};
int main(void) {
char arr[] = "Hello";
f( arr );
}
特别是,我对q < p
比较是否合法感兴趣。
不,不是。使用不指向数组元素或超出数组末尾的指针(即不在范围内[&arr[0], &arr[size]]
)的指针会调用未定义的行为。
C11 标准,6.5.6.8(“加法运算符”):
如果指针操作数和 [of P + N] 的结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。
(强调我的)
不,这是不合法的。指针必须要么指向数组,要么指向数组末尾,要么为空。
ISO C11,附录 J.2“未定义行为”,表示在以下情况下行为未定义:
对数组对象和整数类型的指针进行加法或减法运算会产生不指向或仅超出同一数组对象的结果(6.5.6)。
这是行中的情况
char *q = p - 1;
当p == &arr[0]
, 单行有 UB 会导致整个程序有 UB。请注意,您不必比较指针或取消引用它或任何东西。减法就够了。
我不知道法律,但它肯定没有意义。p 指向数组,这意味着保存数组的地址。q 指向数组之前的一个地址块。每当您比较它们时,您将比较两个连续地址块的地址。结果总是正确的,因为你基本上是在比较 p 和 p-1