为什么再次编译时二进制输出不相等? [英] Why is the binary output not equal when compiling again?

查看:26
本文介绍了为什么再次编译时二进制输出不相等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用构建脚本来编译多个 C# 项目.二进制输出被复制到一个结果文件夹,覆盖以前版本的文件,然后添加/提交到 subversion.

I'm using a build script to compile several C# projects. The binary output is copied to a result folder, overwriting the previous version of the files, and then added/committed to subversion.

我注意到,即使源代码或环境根本没有变化,编译的二进制输出也是不同的.这怎么可能?对于相同的输入,二进制结果不应该完全相等吗?

I noticed that the binary output of the compilation are different even when there was no change to the source or environment at all. How is this possible? Isn't the binary result supposed to be exactly equal for the same input?

我不是有意在任何地方使用任何类型的特殊时间戳,但是编译器(Microsoft,.NET 4.0 中包含的那个)可能会自行添加时间戳吗?

I'm not intentionally using any kind of special timestamps anywhere, but does the compiler (Microsoft, the one included in .NET 4.0) possibly add timestamps itself?

我问的原因是我将输出提交给 subversion,并且由于我们的构建服务器的工作方式,签入的更改会触发重新构建,导致再次修改的二进制文件被签入一个圆圈.

The reason I'm asking is I'm committing the output to subversion, and due to the way our build server works the checked in changes trigger a rebuild, causing the once again modified binary files to be checked in in a circle.

推荐答案

另一个更新:

自 2015 年以来,编译器团队一直在努力从编译器工具链中消除不确定性的来源,以便相同的输入确实产生相同的输出.有关详细信息,请参阅 Roslyn github 上的Concept-determinism"标签.

Since 2015 the compiler team has been making an effort to get sources of non-determinism out of the compiler toolchain, so that identical inputs really do produce identical outputs. See the "Concept-determinism" tag on the Roslyn github for more details.

更新:这个问题是我 2012 年 5 月博客的主题.谢谢你的好问题!

UPDATE: This question was the subject of my blog in May 2012. Thanks for the great question!

这怎么可能?

很容易.

对于相同的输入,二进制结果不应该完全相等吗?

Isn't the binary result supposed to be exactly equal for the same input?

绝对不是.恰恰相反.每次运行编译器都应该得到不同的输出.否则你怎么知道你重新编译了?

Absolutely not. The opposite is true. Every time you run the compiler you should get a different output. Otherwise how could you know that you'd recompiled?

C# 编译器在每次编译时将新生成的 GUID 嵌入到程序集中,从而保证不会有两次编译产生完全相同的结果.

The C# compiler embeds a freshly generated GUID in an assembly on every compilation, thereby guaranteeing that no two compilations produce exactly the same result.

此外——即使没有 GUID,编译器也不保证两个相同"的编译会产生相同的结果.

Moreover -- even without the GUID, the compiler makes no guarantees whatsoever that two "identical" compilations will produce the same results.

特别是,元数据表的填充顺序高度依赖于文件系统的细节;C# 编译器开始按照文件的顺序生成元数据,并且可以通过各种因素巧妙地改变.

In particular, the order in which the metadata tables are populated is highly dependent on details of the file system; the C# compiler starts generating metadata in the order in which the files are given to it, and that can be subtly changed by a variety of factors.

由于我们的构建服务器的工作方式,签入的更改会触发重新构建,导致再次修改的二进制文件被签入一个圆圈.

due to the way our build server works the checked in changes trigger a rebuild, causing the once again modified binary files to be checked in in a circle.

如果我是你,我会解决这个问题.

I'd fix that if I were you.

这篇关于为什么再次编译时二进制输出不相等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆