[英]Building C++ code with different version of Visual Studio produces different file size of .exe?
I can build my own .sln manually on my machine, or have Azure DevOps build it on a remote machine.我可以在我的机器上手动构建自己的 .sln,或者让 Azure DevOps 在远程机器上构建它。 The software is targeting .NET Core 3.1, and using C++17.
该软件面向 .NET Core 3.1,并使用 C++17。 I had noticed that building the same code, from the same branch, produced a different size .exe: the remote one had 9 KB less than the local one.
我注意到从同一个分支构建相同的代码会产生不同大小的 .exe:远程的比本地的少 9 KB。
I finally got the same result when I upgraded the remote machine's version of Visual Studio 2019 to match mine (from 16.8.something up to 16.11.14).当我升级远程机器的 Visual Studio 2019 版本以匹配我的(从 16.8.something 到 16.11.14)时,我终于得到了相同的结果。 But how can this difference be explained?
但是如何解释这种差异呢? Is there something missing from the smaller file?
较小的文件中是否缺少某些内容? It should have all the same methods, logic, and functionality.
它应该具有所有相同的方法、逻辑和功能。 There were no errors, so no part of it could have failed to compile.
没有错误,所以它的任何部分都不会编译失败。
I also have to build Java projects with Maven and have heard that it can be built "slightly differently" depending on Maven versions.我还必须使用 Maven 构建 Java 项目,并且听说它可以根据 Maven 版本“略有不同”构建。 That made sense at first, but in hindsight I don't know exactly what that means.
起初这是有道理的,但事后我不知道这到底是什么意思。
Has anyone been really in the weeds with software builds (specifically with Visual Studio and its C++ compiler) that can explain this concept of "slightly different builds", or has a good idea?有没有人真正在使用软件构建(特别是使用 Visual Studio 及其 C++ 编译器)来解释“略有不同的构建”的概念,或者有一个好主意?
Would both version be functionally identical, or is there no easy way to tell?两个版本在功能上是否相同,或者没有简单的方法来判断?
The C++ standard does not dictate the machine code that should be produced by the compiler. C++ 标准没有规定应该由编译器生成的机器代码。 It just specifies the expected observable behavior .
它只是指定了预期的可观察行为。
So if for example you have a for
loop the standard dictates the behavior (initializing, checking the condition etc.).因此,例如,如果您有一个
for
循环,则标准规定了行为(初始化、检查条件等)。 But you can translate to machine code in various ways, eg using different registers, or executing the statements in different order (as long as the observable behavior is the same).但是您可以通过多种方式转换为机器代码,例如使用不同的寄存器,或者以不同的顺序执行语句(只要可观察的行为相同)。
This principle is called the as-if rule .这个原则被称为as-if rule 。
So different compilers (or compiler versions) can produce different machine code.所以不同的编译器(或编译器版本)可以产生不同的机器代码。 The cause might be either different optimizations, or different ways of translating C++ into machine code (as the mapping between C++ and machine code is not 1-1).
原因可能是不同的优化,或者将 C++ 转换为机器代码的不同方式(因为 C++ 和机器代码之间的映射不是 1-1)。
Examples related to optimizations: if you have various statements in the code that are not dependent (eg you modify different unrelated variable), the compiler/optimizer might re-order them if memory access patern would be more efficient.与优化相关的示例:如果代码中有各种不相关的语句(例如,您修改了不同的不相关变量),如果内存访问模式更有效,编译器/优化器可能会重新排序它们。 Or the compiler/optimizer might eliminate statement that do not have observable behavior (like incrementing a variable that is never read afterwards).
或者编译器/优化器可能会消除没有可观察行为的语句(比如增加一个之后永远不会读取的变量)。 Another example is whether functions are inlined which is entirly up to the compiler/optimizer, and affect the binary code.
另一个例子是函数是否被内联,这完全取决于编译器/优化器,并影响二进制代码。
Therefore there's no guarentee for the size (or content) of a compiled binary file.因此,编译的二进制文件的大小(或内容)没有保证。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.