g ++编译器有一个奇怪的问题。当使用g ++ main.cpp编译程序时,它会给出一个结果,当我输出-O2标志时,它会给出不同的输出。那是为什么?
答案 0 :(得分:9)
GNU g ++编译器的-O2标志的含义
-O
或-Ox
(其中x
是1
,2
或3
之类的数字是优化级别。缺少-O
或-Ox
意味着没有优化。 -O
相当于-O1
。请参阅Options That Control Optimization。
当使用g ++ main.cpp编译程序时,它会给出一个结果,当我输出-O2标志时,它会给出不同的输出。那是为什么?
正如Wooble所说,你的程序中存在未定义的行为。编译器在遇到未定义的行为时可以自由地执行它想要的操作,包括编译您希望的语句,删除未定义的行为或创建demons fly out you nose。
英特尔的ICC编译器对于丢弃具有未定义行为的代码特别无情。我已经看到代码完美无缺地执行Clang,Comeau,GCC和MSVC的自我测试;由于未定义的行为而在使用ICC编译时失败。
如果你的代码神秘失败(就像你的那样),那么你应该在Clang及其消毒剂下运行它。尤其是UB清洁剂(使用-fsanitize=undefined
标志调用,就像-g
或-O
选项一样。每当您的程序执行不应该执行的操作时,您将在stderr
上收到消息。您可以在Clang的Controlling Code Generation找到完整的消毒剂。
您通常可以从发行版的回购中安装Clang。如果您需要下载并安装最新的Clang,请参阅Python的Dynamic Analysis with Clang。该文档将指导您完成从下载和安装到使用消毒剂运行程序的所有步骤。
以下是编写LLVM编译器(Clang是它的前端)的人对Undefined Behavior的更多阅读:
Regehr博士关于Undefined Behavior的博客(感谢Nemanja):