C++ 你能混合c++;使用同一编译器的不同版本编译

C++ 你能混合c++;使用同一编译器的不同版本编译,c++,gcc,abi,gcc4.9,gcc4.6,C++,Gcc,Abi,Gcc4.9,Gcc4.6,例如,我可以将在GCC-4.6中编译的一组库与GCC-4.9混合使用 我知道不同的编译器“品种”如VS不能与MinGW一起使用,但同一编译器的不同代可以吗?是否可能出现问题?如果是什么?您只能混合来自不同编译器或同一编译器的不同版本的生成的二进制文件(如果它们与ABI(应用程序二进制接口)兼容) 例如: 呼叫程序 名称损坏 线程本地存储处理 都是ABI的一部分 如果其中一种情况发生了变化,您会发现,您可能会遇到链接器错误、崩溃或其他形式的意外行为。 一般来说,编译器供应商通常会尝试至少保持与

例如,我可以将在GCC-4.6中编译的一组库与GCC-4.9混合使用


我知道不同的编译器“品种”如VS不能与MinGW一起使用,但同一编译器的不同代可以吗?是否可能出现问题?如果是什么?

您只能混合来自不同编译器或同一编译器的不同版本的生成的二进制文件(如果它们与ABI(应用程序二进制接口)兼容)

例如:

  • 呼叫程序
  • 名称损坏
  • 线程本地存储处理
都是ABI的一部分

如果其中一种情况发生了变化,您会发现,您可能会遇到链接器错误、崩溃或其他形式的意外行为。
一般来说,编译器供应商通常会尝试至少保持与旧版本的向后兼容性,但这并不能保证。正如其他人所说,您必须阅读文档或重新编译所有内容。

同一编译器的不同版本有时可以相互兼容,但并不总是兼容。例如,GCC 4.7.0,这意味着使用4.7.0+和4.7.0-编译的库可能彼此不兼容(因此在您的示例中,使用4.6编译的库将与使用4.9编译的库不兼容)。给定的编译器版本中也可能存在ABI错误:

版本4.7.0和4.7.1对C++标准库的更改,在C++ 11模式中影响了ABI:将数据成员添加到STD::列表改变其大小并更改一些成员函数的定义,而且std::pair的move构造函数非常重要,它改变了具有std::pair参数或返回类型的函数的调用约定。对于GCC版本4.7.2,ABI不兼容已得到修复,但因此,使用GCC 4.7.0或4.7.1编译的C++11代码可能与使用不同GCC版本编译的C++11代码以及使用任何版本编译的C++98/C++03代码不兼容

表示它们试图保持前向兼容性,但不保持后向兼容性:

版本控制使后续版本的库二进制文件能够添加新符号和功能,同时保持与本系列早期版本的兼容性。因此,如果库二进制文件被小心管理的后续库二进制文件替换,则与库二进制文件的初始版本链接的程序二进制文件仍将正确运行。这称为前向兼容性

相反(向后兼容性)是不正确的。在发布系列(添加了附加符号)中,无法获取与库二进制文件的最新版本链接的程序二进制文件,无法在库二进制文件的初始版本中进行替换,也无法保持链接兼容

该页面还对GCC用于标记给定组件的不同版本的版本控制系统进行了相当长的解释,并对GCC本身背后的版本控制进行了解释:

允许的更改

  • 以下内容将导致库次要版本号增加,例如从“libstdc++.so.3.0.4”增加到“libstdc++.so.3.0.5”

  • 添加导出的全局或静态数据成员

  • 添加导出函数、静态或非虚拟成员函数

  • 通过其他实例化添加导出的一个或多个符号

  • 其他允许的更改是可能的

禁止更改

以下非详尽列表将导致库主要版本号增加,例如从“libstdc++.so.3.0.4”增加到“libstdc++.so.4.0”

  • gcc/g++编译器ABI中的更改

  • 更改导出符号的大小

  • 更改导出符号的对齐方式

  • 更改导出符号的布局

  • 更改导出符号上的损坏

  • 删除导出的符号

  • 通过添加或删除基类更改类型的继承属性

  • > P>更改C++标准中指定的类型的大小、对齐方式或布局。这些不一定要在库二进制文件中实例化或导出,并且包括所有必需的语言环境方面,以及std::basic_streambuf等内容

  • 将显式复制构造函数或析构函数添加到本来具有隐式版本的类中。这将改变编译器在按值返回语句或参数中处理此类的方式:编译器将被迫使用内存,而不是在寄存器中传递此类的实例。有关C++详细说明的函数调用约定和API的部分,请参阅进一步的细节。

请注意粗体部分。在一个完美的世界中,具有相同主要发行号的GCC版本将是二进制兼容的。这并不是一个完美的世界,所以在你开始像这样混合编译器版本之前要非常仔细地测试,但一般来说你可能会没事。

你必须阅读编译器的文档。说“同一编译器的不同版本”比说“同一类型的不同编译器”更清楚吗,还是我遗漏了什么?你是在说ABI的概念吗?对于gcc,我建议您在这里查看一下:因此它查找gcc:下面的非详尽列表将导致库的主要版本号增加,例如从“libstdc++.So.3.0.4”增加到“libstdc++.So.4.0.0”。1.gcc/g++编译器中的更改最重要的是,标准库的内部可以更改,因此任何内联的内容都会严重损坏。在VC++中,甚至混合调试和发布CRT都不会因为这个原因而工作。@MatteoItalia我对VC++不太熟悉,并且假设标准库是平台的一部分,因此省略了它