首页 > 解决方案 > &array[i] 总是等价于 (array + i) 吗?

问题描述

最近看到一段C代码是这样的:

#include <stdio.h>

int main(void) {
    int array[5] = {1, 2, 3, 4, 5};

    for (int* ptr = &array[0]; ptr != &array[5]; ptr++)
        printf("%d\n", *ptr);

    return 0;
}

由于 operator在 C[]中的优先级高于 operator &,我认为&array[5]相当于&(*(array + 5)),这会导致未定义的行为(我们不允许取消引用array + 5)。这就是为什么我怀疑上面的代码格式不正确。(顺便说一句,我知道这ptr != array + 5没关系。)

我使用带有编译器标志的 GCC 11.1.0 和 Clang 12.0.0 测试了这段代码-O0 -fsanitize=address,undefined,但两个编译器都解释&array[5]array + 5,并且没有发生意外行为。

总是&array[i]等价于array + i(即使array[i]是无效的)?先感谢您。

标签: cpointerslanguage-lawyerundefined-behavior

解决方案


首先是 6.5.2.1/2:

下标运算符的[]定义E1[E2](*((E1)+(E2)))

然后它在 (6.5.3.2/3) 中定义,一元运算&符:

[...]类似地,如果操作数是运算符的结果,[]&运算符和*隐含的一元都不会[]被评估,结果就好像&运算符被删除并且[]运算符被更改为+运算符一样。

这明确地说这&x[y]意味着(x) + (y)确切。


推荐阅读