使用不同版本的 Visual Studio 构建 C++ 代码会产生不同大小的 .exe 文件?

Building C++ code with different version of Visual Studio produces different file size of .exe?

我可以在我的机器上手动构建我自己的 .sln,或者让 Azure DevOps 在远程机器上构建它。该软件面向 .NET Core 3.1,并使用 C++17。我注意到从同一个分支构建相同的代码会产生不同大小的 .exe:远程的比本地的少 9 KB。

当我升级远程机器的 Visual Studio 2019 版本以匹配我的版本(从 16.8.something 到 16.11.14)时,我终于得到了相同的结果。但如何解释这种差异呢?较小的文件中是否缺少某些内容?它应该具有所有相同的方法、逻辑和功能。没有错误,所以它的任何部分都不会编译失败。

我还必须使用 Maven 构建 Java 项目,并且听说它可以根据 Maven 版本“略有不同”地构建。起初这很有道理,但事后看来我不明白那到底是什么意思。

有没有人真正了解软件构建(特别是 Visual Studio 及其 C++ 编译器)可以解释“略有不同的构建”这一概念,或者有一个好主意?

这两个版本在功能上是否相同,还是没有简单的方法可以分辨?

C++ 标准并未规定编译器应生成的机器代码。它只是指定预期的 可观察行为

因此,例如,如果您有一个 for 循环,则标准会规定行为(初始化、检查条件等)。但是您可以通过多种方式转换为机器代码,例如使用不同的寄存器,或以不同的顺序执行语句(只要可观察到的行为相同)。

这个原则叫做as-if rule

所以不同的编译器(或编译器版本)可以产生不同的机器码。原因可能是不同的优化,或将 C++ 转换为机器代码的不同方式(因为 C++ 和机器代码之间的映射不是 1-1)。

与优化相关的示例:如果您在代码中有各种不相关的语句(例如,您修改了不同的无关变量),如果内存访问模式是 compiler/optimizer 可能 re-order更高效。或者 compiler/optimizer 可能会消除没有可观察行为的语句(比如递增一个以后永远不会读取的变量)。又如函数是否inlined完全取决于compiler/optimizer,影响二进制码

因此无法保证已编译二进制文件的大小(或内容)。