【发布时间】:2014-12-19 09:51:44
【问题描述】:
考虑这个程序:
#include <stdio.h>
int main(void)
{
int x;
while ( 1 == scanf("%d", &x) )
printf("%c\n", "hello"[x]);
}
编译器必须编译成功,因为程序没有UB,只要用户没有输入任何超出0-4范围的数字。
但是,根据this thread UB 可以回到过去。现在考虑这个程序:
int main(void)
{
printf("hello\n");
"hello"[6];
}
对该程序的任何调用都会导致未定义的行为,并且由于它可以穿越时间,因此该程序在任何调用时的整个行为都是未定义的。因此编译器可以拒绝程序而不生成可执行文件吗? (我们可以说 UB 回到了编译阶段!)
【问题讨论】:
-
@Zaffy:
"hello"[5]是'\0',"hello"[6]超出范围。 -
@Jarod42 哦,是的,对不起 :)
-
可靠且可靠地检测未定义行为是一个难以处理或无法确定的问题......
-
是的,完美的例子是
constexpr,在这些情况下我们可以看到clang和gccreject most undefined behavior at compile time。 -
请注意,在 UB 的情况下中止编译很常见:例如,Gcc 在
void foo(void) { extern int n; } static int n;上中止,尽管这是 UB 而不是违反约束。不过,IMO,你的例子有点不同。
标签: c++ c language-lawyer undefined-behavior