经过一长串调试后,我将问题缩小到一个文件。问题是当其他一切都相同时,文件在两个不同目录中的编译方式不同。
我正在使用 CodeSourcery 的 arm gcc 编译器(gcc 版本 4.3.3,Sourcery G++ Lite 2009q1-161)来编译一个简单的文件。我在一个模块中使用它没有任何问题,然后我将它复制到另一个模块以在那里使用。编译时,目标文件明显不同。编译这两个文件的命令行是相同的(我使用 linux 历史来确定),3 个包含文件也是相同的副本(用 diff 检查)。
我对这两个目标文件进行了二进制比较,它们散布着许多单独的字节差异。我对两者都做了一个 objdump -D 并比较了它们,发现有很多不同之处。这是 dump1 , dump2 , 和 diff .命令行是“ arm-none-eabi-gcc --std=gnu99 -Wall -O3 -g3 -ggdb -Wextra -Wno-unused -c crc.c -o crc.o"。
这怎么可能?我还使用 -S 而不是 -c 进行了编译,并查看了汇编程序输出,除了目录路径外,其他都是一样的。那么目标文件怎么会不一样呢?
我真正的问题是,当我尝试将 dump2 的对象文件链接到我的程序时,出现 undefined reference 错误,因此对象中的某些内容是错误的,而 dump1 的对象没有此类错误并且链接正常。
最佳答案
对于大型软件,许多实现都在对指针进行哈希处理。这是造成结果随机化的主要原因之一。通常如果程序逻辑正确,一些内部数据结构的顺序可能不同,这在大多数情况下是无害的。
另外,不要比较“objdump -D”的输出,因为您是从不同的目录编译代码,字符串表、符号表、DWARF 或 eh_frame 应该不同。你肯定会得到很多差异线。
唯一有意义的比较是比较“objdump -d”的输出,它只处理文本部分。如果文本部分相同(相似)则可以认为是相同的。
关于c - 编译相同的源代码如何生成不同的目标文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24151453/