首页 > 解决方案 > C++ 代码在不同操作系统上的编译方式不同

问题描述

我想知道为什么 c++ 代码在不同版本的操作系统上编译不同。例如,在操作系统上编译相同的代码时,不会出现任何警告或任何问题,但是当在不同的操作系统上编译相同的代码时,就会出现警告或错误。

那么为什么会发生这种情况。gcc 版本之间的区别是什么,或者当 c++ 代码在两个不同的操作系统(如 Ubuntu 14 和 Ubuntu 16)上编译时,它实际上是什么使 c++ 代码独一无二。我只是想了解 c++ 代码对操作系统编译的独特之处。

标签: c++ubuntucompilationoperating-system

解决方案


C++ 作为一种语言是由其标准定义的。该标准是一个巨大的律师行话文档,它定义了语言的语法、规则、标准库以及一些关于编译器应该如何正确处理源代码的指南。编译器是抽象语言和真实可执行程序之间的桥梁,由不同的供应商或组织实现,并且应该尽可能地遵守该标准。在实践中,它们的正确性各不相同[1]

许多编译器错误是标准的一部分(标准的诊断),因此原则上应该在编译器之间基本相同[2]。编译器警告通常技术性较低,并且通常是编译器供应商试图帮助您捕获在技术上不是格式错误的程序的常见编程错误的方式。根据标准,程序可能格式错误,这意味着它在语法上无效并且不代表真实的程序。标准要求编译器为格式错误的程序发出诊断。

然而,程序可能会出现错误的更小、更微妙的方式,例如使用标准所指的未定义行为(UB) 和实现定义的行为. 在这些情况下,标准没有指定编译器应该如何正确地将源代码翻译成程序,并且编译器供应商在法律上被允许按照他们喜欢的方式进行。虽然许多编译器生成的代码可能与您期望的差不多,但在程序中调用未定义的行为通常是一个非常糟糕的主意,因为无法保证您的程序将如何运行。在一个编译器上安静地编译并通过测试的 UB 代码可能会在另一个编译器上测试失败或完全编译失败,或者在最坏的时间遇到​​错误。如果您使用特定于编译器的语言扩展,情况也会变得棘手。

当面对潜在的 UB 时,一些编译器可能会提供非常有用的建议,而其他编译器可能会误导性地保持沉默。最佳实践是通过从良好的来源学习 C++并仔细阅读文档(包括C++ 语言文档和您可能使用的任何库的文档)来熟悉 UB 的原因。

[1] 在https://en.wikipedia.org/wiki/List_of_compilers#C++_compilers中查看 C++ 编译器列表的“标准一致性”列

[2] 三个非常流行的编译器的错误消息和警告的比较:https ://easyaspi314.github.io/gcc-vs-clang.html


推荐阅读