是否允许C ++编译器发出编译同一程序的不同机器代码?

时间:2010-06-16 13:59:08

标签: c++ compiler-construction compilation

考虑一下情况。我们有一些特定的C ++编译器,一组特定的编译器设置和一个特定的C ++程序。

我们使用该编译器和那些设置编译特定程序两次,每次都进行“清理编译”。

发出的机器代码是否应该相同(我不是指时间戳和其他花里胡哨,我的意思是只会执行真正的代码),还是允许从一个编辑到另一个编辑不同?

4 个答案:

答案 0 :(得分:5)

C ++标准当然没有说出任何可以防止这种情况发生的事情。但实际上,编译器通常是确定性的,因此在给定相同输入的情况下,它将产生相同的输出。

真正的问题主要是它认为作为输入的环境的哪些部分 - 有一些很少似乎假设构建机器的特征反映了目标的特征,并改变了它们的输出基于构造环境中隐含的“输入”而不是显式声明,例如通过编译器标志。也就是说,即使这是相对不寻常的。规范是输出依赖于显式输入(输入文件,命令行标志等)

答案 1 :(得分:4)

无法保证它们是相同的。同样根据http://www.mingw.org/wiki/My_executable_is_sometimes_different

  

当我编译并重新编译相同的源时,我的可执行文件有时会有所不同。这是正常的吗?

     

是的,默认情况下,根据设计,~MinGW的GCC不会产生ConsistentOutput,除非你修补它。

编辑:发现this post似乎解释了如何使它们相同。

答案 2 :(得分:4)

根据标准中的 as-if 规则,只要符合程序(例如,没有未定义的行为)无法区分,编译器就可以做任何想做的事情。换句话说,只要程序产生相同的输出,禁止这一点的标准就没有限制。

从实际的角度来看,我不会使用编译器来构建生产软件。我希望能够重新编译两年前发布的版本(使用相同的编译器等)并生成相同的机器代码。我不想担心我无法重现错误的原因是编译器今天决定做一些稍微不同的事情。

答案 3 :(得分:1)

我敢打赌,由于某些元数据编译器写入,它每次都会变化(例如,c#编译的dll总是在某些字节中变化,即使我连续两次“构建”而没有改变任何东西)。但无论如何,我永远不会依赖它不会改变。