是否允许 C++ 编译器发出编译同一程序的不同机器代码?

     2023-02-21     41

关键词:

【中文标题】是否允许 C++ 编译器发出编译同一程序的不同机器代码?【英文标题】:Is a C++ compiler allowed to emit different machine code compiling the same program? 【发布时间】:2011-03-04 11:48:38 【问题描述】:

考虑一种情况。我们有一些特定的 C++ 编译器、一组特定的编译器设置和一个特定的 C++ 程序。

我们使用该编译器和这些设置编译该特定程序两次,每次都进行“干净编译”。

发出的机器代码应该相同(我不是指时间戳和其他花里胡哨的东西,我的意思是只有将要执行的真实代码)还是允许它在不同的编译中有所不同?

【问题讨论】:

@Neil Butterworth 回答了同样的问题。 IIRC,他解释了为什么即使一切似乎都相同,编译器也会产生不同的输出。我正在寻找它:) 这听起来像是一个技巧问题;) 如果编译器在某些情况下使用统计算法,那么是的,它可能会产生稍微不同的代码,即使用替代寄存器或代码布局。 标准是否说明了机器代码?不?那么,允许any 输出保留标准中指定的语义。尔格:是的。 您的编译器是否设置了随机化函数地址以防止有针对性的缓冲区溢出攻击? 【参考方案1】:

C++ 标准当然没有说什么来防止这种情况发生。然而,实际上,编译器通常是确定性的,因此给定相同的输入,它会产生相同的输出。

真正的问题主要是它认为环境的哪些部分作为其输入 - 有一些 似乎假设构建机器的特征反映了目标的特征,并改变了它们的输出基于构建环境中隐含而不是明确声明的“输入”,例如通过编译器标志。也就是说,即使这样也相对不寻常。规范是输出依赖于显式输入(输入文件、命令行标志等)

顺便说一句,我只能想到一件“自发”改变的相当明显的事情:一些编译器和/或链接器将时间戳嵌入到它们的输出文件中,因此输出文件的几个字节会从一个构建更改为下一个构建--但这只会出现在文件中嵌入的元数据中,不会更改生成的实际代码。

【讨论】:

我会为一个即时发明优化的非确定性编译器提供什么。 Visual Studio 提供配置文件引导优化。【参考方案2】:

根据标准中的 as-if 规则,只要符合标准的程序(例如,没有未定义的行为)无法区分,编译器就可以为所欲为。换句话说,只要程序产生相同的输出,标准中就没有禁止这样做的限制。

从实际的角度来看,我不会使用执行此操作的编译器来构建生产软件。我希望能够重新编译两年前发布的版本(使用相同的编译器等)并生成相同的机器代码。我不想担心我无法重现错误的原因是编译器决定今天做一些稍微不同的事情。

【讨论】:

出于多种目的,让编译器的输出是完全确定的,即使它不是最优的也是很有用的。例如,如果正在为开源投票机编译代码,则应该使用开源交叉编译器,无论编译器本身运行的环境如何,它总是会产生位相同的输出。如果通过多种独立方式从源代码引导的编译器版本都生成相同的代码,这将非常强烈地暗示编译器没有隐藏任何不在源代码中的“陷阱”。【参考方案3】:

无法保证它们会相同。也照http://www.mingw.org/wiki/My_executable_is_sometimes_different

当我编译和重新编译相同的源代码时,我的可执行文件有时会有所不同。这正常吗?

是的,默认情况下,根据设计,~MinGW 的 GCC 不会产生 ConsistentOutput,除非你修补它。

编辑:发现 this post 似乎解释了如何使它们相同。

【讨论】:

我点击了链接,但没有解释原因! @martin York 用另一个链接更新了我的帖子以使它们相同。【参考方案4】:

我敢打赌,由于某些元数据编译器写入,它每次都会有所不同(例如,c# 编译的 dll 总是在某些字节上有所不同,即使我连续“构建”两次而不更改任何内容)。但无论如何,我永远不会相信它不会改变。

【讨论】:

同一个c语言程序,若在两台不同指令系统的机器上运行,编译后的程序是不是一样?能否用同一个编译器编译?

RT如果生成的程序不是在本机上运行的话,这种编译器叫做crosscompiler不是crosscompiler的话,生成的程序就只能在本机以及与本机具有相同指令集的机器上运行了追问编译后的程序是否一样???追答指令集不一样的话,生成的二... 查看详情

是否有编译为机器代码的 C C++ C# 编译器 [关闭]

】是否有编译为机器代码的CC++C#编译器[关闭]【英文标题】:IsthereaCC++C#compilerthatcompilestomachinecode[closed]【发布时间】:2014-11-2323:10:20【问题描述】:我正在寻找一种将小型计算密集型程序编译为机器代码可执行文件的方法。该程... 查看详情

使用 GCC 将 C++ 应用程序静态编译成二进制文件

】使用GCC将C++应用程序静态编译成二进制文件【英文标题】:StaticallycompileaC++appwithGCCintoabinary【发布时间】:2012-10-2908:14:09【问题描述】:如何在面向unix的Ubuntu机器上使用GCC静态编译应用程序?我将如何定位32位/64位机器和具有... 查看详情

第4章jit编译器

...型语言在执行前需要编译成机器码,不同的CPU需要不同的编译器,编译成功后在同一台机器不需再次编译。以Python为代表的解释型语言,解释器一行一行的解释执行Python代码。  编译型语言的优势在于跨平台,只要平台能够提... 查看详情

c++中#if#ifdef的作用

用编译器经常会自动生成这些,我自己很少用,想知道经常用的这些的介绍,谢谢了。谢谢大家的回答有没有那本书里面有比较详细一点的介绍类似的这些作用,或者给个超链接一般情况下,源程序中所有的行都参加编译。但是... 查看详情

求助:为啥我编的c++程序在自己电脑上能正常运行,但编译后挂在后台linux系统下就总是运行一半后出错,

...,这到底是为神马啊!!!求大神指导!!!机器不同,编译出为的目标代码就不同,这就是为什么总有人说C程序不好的一个原因。C编译出来的代码是与当前机器类型和操作系统直接相关的!一模一样的机器,不同的操作系统... 查看详情

不同版本的 C++ 库

...:2010-09-1009:16:13【问题描述】:在vista上使用VisualStudio2008编译一个简单的C++项目后,一切都在原始vista机器和其他vista计算机上运行良好。但是,将其移至XP框会导致错误消息:“应用程序无法启动,因为应用程序配置不正确”。... 查看详情

c++程序不同环境就很卡

...要安装配置环境的,因为c/c++直接对当前所在的平台进行编译,它所编译好的字节码就是当前平台可识别的机器指令。这也是c/c++的缺点,编译好的程序并不能跨平台使用。 查看详情

是否需要在同一环境中使用同一编译器对同一程序进行编译之间保持一致的未指定和未定义行为?

】是否需要在同一环境中使用同一编译器对同一程序进行编译之间保持一致的未指定和未定义行为?【英文标题】:Areunspecifiedandundefinedbehaviorrequiredtobeconsistentbetweencompilesofthesameprogramwiththesamecompilerinthesameenvironment?【发布时间】... 查看详情

是否需要在同一环境中使用同一编译器对同一程序进行编译之间保持一致的未指定和未定义行为?

】是否需要在同一环境中使用同一编译器对同一程序进行编译之间保持一致的未指定和未定义行为?【英文标题】:Areunspecifiedandundefinedbehaviorrequiredtobeconsistentbetweencompilesofthesameprogramwiththesamecompilerinthesameenvironment?【发布时间】... 查看详情

C++ 和 C 是不是使用相同类型的链接器?

...链接过程中是否使用同一种链接器?还有,对于C++和C的编译器,C++编译器是建立在C编译器之上的吗?【问题讨论】:链接根本不是编译过程的一部分。链接是一个完全不同的过程,它发生在编译完成之后。如果C++编译器 查看详情

java中多态是啥意思?

...式即为多态。引用CharlieCalverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术... 查看详情

发出c++代码system()调用外部编译器编译其他c++代码

】发出c++代码system()调用外部编译器编译其他c++代码【英文标题】:Issuec++codesystem()tocallexternalcompilertocompileotherc++code【发布时间】:2016-08-0308:46:10【问题描述】:我正在使用Qt创建一个项目,该项目编译具有一个.cpp文件或多个.cpp... 查看详情

c++ 中的 final 关键字是不是允许额外的编译器优化?

】c++中的final关键字是不是允许额外的编译器优化?【英文标题】:Doesfinalkeywordinc++allowforadditionalcompileroptimizations?c++中的final关键字是否允许额外的编译器优化?【发布时间】:2015-03-1006:20:45【问题描述】:我在考虑虚拟通话及... 查看详情

在 Windows 中编译的 C++ 程序产生不同的输出

】在Windows中编译的C++程序产生不同的输出【英文标题】:C++programcompiledinwindowsproducesdifferentoutput【发布时间】:2015-07-1316:50:46【问题描述】:我正在解决一个涉及递增计数器并显示它的问题。我初始化和增加变量的方式似乎很正... 查看详情

优化c++软件

8.2. 不同编译器的比较我在7个不同品牌的C++编译器上进行了一系列实验,看它们是否能够进行各种优化。结果汇总在表8.1中。这个表展示了在我的测试例子中,不同的编译器是否成功应用了各种优化方法以及代数... 查看详情

针对不同目标的 c++ 强制转换(编译器)

】针对不同目标的c++强制转换(编译器)【英文标题】:c++castingfordifferenttargets(compilers)【发布时间】:2019-05-2110:29:25【问题描述】:鉴于以下情况:code-link为了方便起见,这里是代码本身(我不确定我的链接是否有效):#include... 查看详情

第一周java学习总结(代码片段)

...无关性平台无关性:C或C++是依赖平台的,C或C++源程序的编译器针对平台进行编译,而不同的平台有不同的机器指令,所以C或C++无法跨平台。Java语言提供的编译器不针对特定的操作系统和CPU进行编程,而是针对Java虚拟机把Java源... 查看详情