【发布时间】:2016-03-12 14:22:48
【问题描述】:
我有以下程序:
#include <stdio.h>
int main() {
int v[100];
int *p;
for (p = &(v[0]); p != &(v[100]); ++p)
if ((*p = getchar()) == EOF) {
--p;
break;
}
while (p != v)
putchar(*--p);
return 0;
}
这是gcc --version 在终端上的输出:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin15.3.0
Thread model: posix
为什么在数组的最后一个之后获取元素的地址不会给我任何警告,但例如获取v[101] 的地址会给我以下警告
test.c:8:29: warning: array index 101 is past the end of the array (which
contains 100 elements) [-Warray-bounds]
for(p = &(v[0]); p != &(v[101]); ++p)
^ ~~~
test.c:5:5: note: array 'v' declared here
int v[100];
^
1 warning generated.
我知道索引元素超出缓冲区的范围是未定义的行为,那么为什么编译器不抱怨第一种情况呢?
【问题讨论】:
-
如果在 EOF 之前只读取了零个字符,您的程序将调用 未定义的行为。
-
你不应该在
EOF之后减少p。 -
@chqrlie 你这么说是因为在下面的while循环中我先递减
p然后取消引用它? -
@nbro:完全正确。
p指向第一个循环读取的最后一个有效字符的过去,因为您读取了 100 个字符或因为您到达了文件末尾。因此,当您从第一个循环中断时,不要增加p。顺便说一句,这将解决 MikeCAT 在他的评论中暗示的问题。
标签: c arrays clang undefined-behavior