【发布时间】:2021-06-18 03:59:24
【问题描述】:
最近看到一个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;
}
由于在 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] 无效)?提前谢谢你。
【问题讨论】:
-
你是对的,
&array[5]等同于&(*(array + 5)),但我认为两者都是有效的。两者实际上都没有取消引用指针。他们只是用它来做指针算术。 -
一般来说,你需要一个
sizeof()来确定每个元素的偏移量。 -
可能重复:stackoverflow.com/questions/38915128/… 用标准的引用回答您的问题:§6.5.3.2 “...如果操作数是一元 * 运算符的结果,则该运算符和 &运算符被评估,结果好像两者都被省略了”所以没有未定义的行为。
-
如果我是你,我会使用
array + i以防万一。 “上面的代码格式错误” 格式错误的意思是“需要编译错误”,所以不是这样。 -
@pjs,我不明白你的说法。指针运算已经在元素大小的步骤中执行,那么
sizeof会完成什么?能举个例子吗?
标签: c pointers language-lawyer undefined-behavior