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