我有以下代码:
main ()
{
printf("Hello world !");
*(int *)(0) = 0;
}
当我编译此代码并运行时,它没有将字符串打印到控制台。 在那之后,我修改了一点:
main ()
{
printf("Hello world !\n");
*(int *)(0) = 0;
}
并且,它有效!
我认为背后的谜团是*(int *)(0) = 0;
,但不知道为什么!
聚苯乙烯。我正在使用gcc 4.8.2进行编译。
答案 0 :(得分:6)
直接原因是FILE *
操作被缓冲,特别是stdout
通常是行缓冲的(至少它是交互式的)。如果没有看到\n
且在崩溃之前未显式调用fflush
,则实际上不会将任何内容写入底层文件描述符。
更大的问题是解除引用NULL
指针是未完成行为。对可能发生的事情绝对没有限制。如果编译器可以证明printf
将始终返回,则允许UB在调用之前传播到,使整个main
UB。也就是说,编译器很难证明这一点,特别是因为FILE
通常涉及vtable,所以它实际上并不正确。但关键是你甚至不能相信UB要等到特定的时间。
答案 1 :(得分:0)