在我的帖子“关于不写 return 的 int 型函数”内,我从大家的回答中,得出了这样一个结论:除 main() 以外,只要一个非 void 函数不加 return,程序中就一定有 UB。 但是,下面这段代码让我改变了这个看法。
#include<bits/stdc++.h>
int _(){exit(0);}
int main(){_();}
在此之间,_() 函数没有返回是显而易见的,函数内也仅仅只有一句 exit(0)。我想,这段代码应该会有警告吧。然而我在 Dev-C++ 编译时,编译器竟毫无警告地让代码通过了(我的编译器有开 -Wall,-Wextra);而当我把这段代码放在评测机上一测时,评测结果也一改之前的 MLE(在上述帖子中也有说明),而变成了 WA。
看到这个结果,我尤为惊讶。我又换了一段含含 UB 函数(同时也含 exit(0))的代码,再次测了测:
#include<bits/stdc++.h>
int _(){printf("%d",1u);exit(0);}
int main(){_();}
在我在本地测试时,虽然程序跳过了那句 printf("%d",1u)(没有输出),但这句话竟然“逃”过了编译器的测试,没让编译器报警告。但是,当我把那句 exit(0) 删除后,即便把 main() 对 _() 的调用删除,printf("%d",1u) 也逃不过编译器的搜寻,仍让编译器发出了警告。
“将上面的 printf("%d",1u) 移到 main() 内,情况会怎样呢?”带着这样的疑问,我又将代码改了改。
#include<bits/stdc++.h>
int main(){printf("%d",1u);}
看着这段代码,我原以为,编译器还会像上面那样报警告。谁知,在本地,编译器也仿佛把这个 UB 当成不存在似的,不报警告便让代码成功运行了,并输出了正确结果:1。
看到这么多代码都出乎意料地没让编译器警告,我再次提出了问题:为什么一句短短的 exit(0),就可以帮函数里含 UB 的代码“隐身”,既不让编译器报错,也不让那段语句执行?而在本地时,有些 UB 代码在 main() 内时,这些代码为什么可以不报警告地成功运行?