将指向数组开头的指针与指向数组开头之前的相同类型的指针进行比较是否合法?

时间:2013-07-18 08:41:10

标签: c language-lawyer

这个程序合法吗?如果是这样,请参考其中一种语言标准,支持您的主张(无论哪种方式)。

void f(char *p) {
    char *q = p - 1;
    (void)( q < p );
};

int main(void) {
    char arr[] = "Hello";
    f( arr );
}

特别是,我对q < p比较是否合法感兴趣。

3 个答案:

答案 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