&array[i] 总是等价于 (array + i) 吗?

use*_*574 4 c pointers undefined-behavior language-lawyer

最近看到一段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;
}
Run Code Online (Sandbox Code Playgroud)

由于运算[]&在 C 中优先于运算符,因此我认为&array[5]等效于&(*(array + 5)),这会导致未定义的行为(我们不允许取消引用array + 5)。这就是为什么我怀疑上面的代码格式错误。(顺便说一下,我知道这ptr != array + 5没关系。)

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

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

M.M*_*M.M 9

首先是 6.5.2.1/2:

下标操作符的定义[]E1[E2]相同(*((E1)+(E2)))

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

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

这是明确的&x[y]意思(x) + (y)