我正在使用Arduino core for ESP8266开发ESP8266应用程序。在不同的机器上编译项目后,我发现两个* .bin文件都有很大差异。
我用空项目重现了这种行为。编译后的结果是:
设备1:
程序Sketch1大小:221.999字节(使用1.044.464字节的21% 最大值)(0,97秒)最小内存使用量:31564字节(81920的39%) 字节最大值)
设备2:
程序Sketch1大小:221.995字节(使用1.044.464字节的21% 最大值(0,63秒)最小内存使用量:31568字节(81920的39%) 字节最大值)
将* .bin文件与十六进制编辑器进行比较显示出很大的差异。 我认为在不同设备上编译相同的应用程序应该生成完全相同的文件。
我无法检测到机器之间的单一差异。编译器是否可以在不同的机器上生成不同的文件,或者可能是什么问题?
修改 我找到了4字节差异的原因:编译器在* .bin文件中编译ESP8266库的路径4次。由于windows用户名不同(1个字符长度差异),因此加起来为4个字节。这解释了不同的文件大小,但没有解释文件内部的差异。
为了向您展示我上传文件的差异:
文件显示多个差异。请注意,这是一个空项目,更复杂的项目显示出更多的差异。
所以要说明一点:为什么编译的* .bin文件中存在差异?
答案 0 :(得分:3)
我假设代码定义良好,因为对于具有未定义行为的代码,编译器可能会表现得很好。
即使这是不可取的,编译器在不同的机器上甚至在同一台机器上的不同调用上生成不同但希望功能相同的代码并不罕见。
编译给定程序时,通常会有许多任意选择,除非编译器程序员非常小心,否则很容易构造一个编译器,根据执行之间发生变化的事情做出这些选择,例如元素的地址。内部数据结构。为了解决这个问题,编译器的这个方面可能不像正确性那样经常被测试。只要代码是正确的,人们通常不关心编译器是不确定的。
答案 1 :(得分:1)
之前已经提出并回答了这个问题。没有理由假设,即使你说一个空项目,你每次从编译代码得到相同的二进制文件。人们希望同一台机器在同一天完全相同的源代码等。但是有些编译器会在文件中添加日期/时间戳,所以即使在那里你也可能会有所不同。至于机器代码,虽然有多种方法可以生成与高级语言匹配的功能代码,同一个编译器具有不同的选项或不同的编译器或同一编译器的不同版本,甚至不同的系统库编译器可以产生不同的结果
一般期望相同的源代码产生相同的二进制文件是问题,期望。您应该期望编译器生成与您的源代码功能匹配的代码。
此外,您正在检查"二进制文件"其中包括调试信息和其他项目,其中只有一部分是重要的机器代码,其余部分用于反汇编或调试或加载/编程等。除了机器代码不必匹配,额外的东西没有匹配任何一个共享系统库用于创建该二进制文件(unix方式)并不罕见,因此您可以使用"完全相同的"编译器和源代码,但对同一版本的操作系统进行了不同的更新,如果检查"二进制文件"仍会得到不同的结果。
希望不再是练习,但回到turbo / borland编译器时,其中一个编译器会用内存中的任何内容填充结构。所以说你正在研究它在ram中的一些大程序,你关闭编辑器出于某种原因,后来你编译了一个程序,他们需要256字节的结构/字符串,但你只初始化200,其他56字节将是什么是留在ram中,他们不会先将它归零,所以不仅先前运行的随机内容最终都会出现在"二进制"中,每次编译后随机内容可能会也可能不会相同,即使机器代码和其他一切匹配。再次希望今天不是练习,通常他们将填充归零,但过去曾发生过商业付费编译器。