不同的海湾合作委员会方言可以链接在一起吗?

Can different GCC dialects be linked together?

本文关键字:链接 在一起 方言 委员会      更新时间:2023-10-16

我知道原则上这可能是未定义的行为,但为了处理大型项目,这是我关于 GCC 的问题:

假设我使用完全相同的编译器安装,用gcc -std=c++98编译一个转换单元,用-std=c++11编译另一个转换单元。是否有任何保证可以链接两个目标文件并获得定义良好的程序?

据我所知,由于宏不同,潜在的问题只能来自库头的不同视图,而这些视图充其量只会向标准库类添加新的成员函数,但永远不会添加新的成员对象。

这会以某种方式使使用不同语言方言选项编译更大项目的不同部分变得可以接受吗?

更新:我应该添加一个正交问题:使用两个不同版本的 GCC(比如 4.3 和 4.6),但使用相同的方言选项(-std=c++98)怎么样?此 GCC 文档中的列表似乎表明该库在 4.2.2 和 4.6 之间的两个方向上都是兼容的。

先验的,没有。 最安全的解决方案是假设所有编译器选项都相同,除非编译器专门记录该选项不会影响二进制兼容性。 (大多数编译器都非常缺乏的文档。 在实践中,由于缺乏文档,控制警告的选项( -W... 在 g++ 中)不会影响二进制兼容性,而影响代码生成的选项(语言级别等)可能: g++ 通常保持不同优化级别的兼容性,而 VC++ 则不然。

另一个真正的问题是在命令行中定义预处理器符号。 同样,最安全的选择是所有定义都是相同的,但同样,一些常识是有序的:很难期望标准库是使用项目中使用的预处理器符号编译的(比如MYPROG_CONFIG_FILE_LOCATION)。 另一方面,请注意,_GLIBCXX_DEBUG_GLIBCXX_DEBUG_PEDANTIC的预处理器定义会影响二进制兼容性(尽管 g++ 确保如果你始终使用它们,您将获得一个适用于它们的库版本)。

关于你的问题:由于标准版本,我预计不会对二进制兼容性产生太大影响,但如果选择影响一些预定义的预处理器符号,以一种破坏库中二进制兼容性的方式,我不会感到惊讶,就像你用_GLIBCXX_DEBUG编译了一些模块一样, 有些没有。 它可能会起作用,但我不会指望它。

我知道原则上这可能是未定义的行为,

不是。

假设我使用完全相同的编译器安装,用gcc -std=c++98编译一个转换单元,用-std=c++11编译另一个转换单元。是否有任何保证可以链接两个目标文件并获得定义良好的程序?

是的,这是受支持且有效的(也有例外,例如在一个对象而不是另一个对象中启用调试模式,或者使用显式 ABI 更改选项,例如在一个对象而不是另一个对象中-fshort-enums,但这应该是显而易见的,因为即使您对两个对象使用相同的-std选项,这也不起作用)。

据我所知,由于宏不同,潜在的问题只能来自库头的不同视图,而这些视图充其量只会向标准库类添加新的成员函数,但永远不会添加新的成员对象。

右。

这会以某种方式使使用不同语言方言选项编译更大项目的不同部分变得可以接受吗?

对于海湾合作委员会来说,是的,绝对是。作为证明没问题,请考虑libstdc++.so本身包含一些使用 -std=c++98 构建的对象和一些使用 -std=c++14 构建的对象。

更新:我应该添加一个正交问题:使用两个不同版本的 GCC(比如 4.3 和 4.6),但使用相同的方言选项(-std=c++98)怎么样?此 GCC 文档中的列表似乎表明该库在 4.2.2 和 4.6 之间的两个方向上都是兼容的。

不是两个方向,您需要使用 GCC 4.6(或更高版本)中的libstdc++.so,因为使用该版本编译的对象可能依赖于较新版本中引入的符号,而旧libstdc++.so库中不存在的符号。

https://stackoverflow.com/a/49119902/981959 的一些相关信息

语言ABI是相同的,但STL ABI是不同的。见 https://gcc.gnu.org/wiki/Cxx11AbiCompatibility

因此,不建议混合使用 -std=c++98 -std=c++11 编译的库。跨图像边界传递数据时可能会发生崩溃。

(如果您只调用外部"C"函数并仅传递 POD,则它可能有效)。

另请参阅相关: 使用 GCC 混合不同的C++标准