当*(int*)(0)= 0时,为什么printf不起作用; 存在

Tùn*_*Pun -3 c

我有以下代码:

main ()
{
    printf("Hello world !");
    *(int *)(0) = 0;
}
Run Code Online (Sandbox Code Playgroud)

当我编译此代码并运行时,它没有将字符串打印到控制台.在那之后,我修改了一点:

main ()
{
    printf("Hello world !\n");
    *(int *)(0) = 0;
}
Run Code Online (Sandbox Code Playgroud)

而且,它工作!

我认为背后的奥秘是*(int *)(0) = 0;但不知道为什么!

PS.我正在使用gcc 4.8.2进行编译.

o11*_*11c 6

直接原因是FILE *操作被缓冲,stdout特别是通常是行缓冲的(至少是交互式的).如果\n看不到并且fflush在崩溃之前没有显式调用,则实际上不会将任何内容写入底层文件描述符.

更大的问题是取消引用NULL指针是不明确的行为.对可能发生的事情绝对没有限制.如果编译器可以证明printf将始终返回,则允许UB在调用之前传播到整个mainUB.也就是说,编译器很难证明这一点,特别是因为FILE通常涉及vtable,它实际上并不是真的.但关键是你甚至不能相信UB要等到特定的时间.