我知道,在原则上,这可能是不确定的行为,但在处理大型项目的利益,这是我对GCC的问题:
假设我编译一个TRANSATION单元与gcc -std=c++98
,和另一个与-std=c++11
,使用完全相同的编译安装。 有没有任何形式的保证,我可以链接两个目标文件,并获得一个明确的计划?
据我所知道的,潜在的问题只能来自于由于不同的宏不同意见的库头,而这些反过来会新成员函数,但从来没有成员对象,最好添加到标准库类。
这会在某种程度上使之接受编译不同的语言方言选择一个更大的项目的不同部分?
更新:我要补充一个正交的问题:关于使用两种不同版本的GCC(比如4.3和4.6)的是什么,但西隧同一种方言的选项( -std=c++98
)? 上市这个GCC文档中似乎表明,该库是在4.2.2和4.6之间的双向兼容。
先验的,没有。 最安全的办法是假设所有的编译器选项是相同的,除了当编译器专门记录了该选项不影响二进制兼容性。 在实践中,缺乏文档(这是非常在大多数编译器缺乏的。文档),这似乎是一个安全的赌注,它控制警告(选项-W...
以g ++)不会影响二进制兼容性,并选择其中影响代码生成(语言水平等)可能:克++一般保持在不同级别的优化,其中,作为VC ++不兼容。
另一个实际问题是定义在命令行预处理符号。 同样,最简单的办法是,所有的定义是相同的,但也同样,一些常识是为了:人们很难指望已编译与在项目中使用预处理器符号(如物联网的标准库MYPROG_CONFIG_FILE_LOCATION
,说)。 在另一方面,要注意的预处理器定义_GLIBCXX_DEBUG
和_GLIBCXX_DEBUG_PEDANTIC
会影响二进制兼容性(虽然G ++保证你会得到一个库版本,如果你坚持使用他们与他们的工作)。
至于你的问题:我不希望对二进制兼容性由于标准版本太大的影响, 但它几乎没有让我感到吃惊,如果选择会影响一些预先定义预处理符号,在这样会破坏库的二进制兼容性的方式,就像如果你整理了一些与模块的_GLIBCXX_DEBUG
,有的没有。 它可能工作,但我不会指望它。
我知道,在原则上,这可能是不确定的行为,
不是。
假设我编译一个TRANSATION单元与gcc -std=c++98
,和另一个与-std=c++11
,使用完全相同的编译安装。 有没有任何形式的保证,我可以链接两个目标文件,并获得一个明确的计划?
是的,这是支持和工程(也有例外,比如使调试模式在一个对象,而不是其他,或者使用类似明确-ABI-更改选项-fshort-enums
的一个,而不是其他的,但应该是显而易见的,因为如果您使用相同的甚至不会工作-std
选项两个对象)。
据我所知道的,潜在的问题只能来自于由于不同的宏不同意见的库头,而这些反过来会新成员函数,但从来没有成员对象,最好添加到标准库类。
对。
这会在某种程度上使之接受编译不同的语言方言选择一个更大的项目的不同部分?
对于GCC,是的,绝对。 为了证明它的确定,考虑libstdc++.so
本身包含有内置的一些对象-std=c++98
和一些内置有-std=c++14
。
更新:我要补充一个正交的问题:关于使用两种不同版本的GCC(比如4.3和4.6)的是什么,但西隧同一种方言的选项(-std = C ++ 98)? 这GCC文档中的上市似乎表明,该库是在4.2.2和4.6之间的双向兼容。
不能在两个方向上,你需要使用libstdc++.so
从GCC 4.6(或更新版本),因为该版本编译的目标可能取决于在新版本中引入并没有出现在旧的那个符号libstdc++.so
图书馆。
在一些相关的信息https://stackoverflow.com/a/49119902/981959
语言ABI是一样的,但是STL ABI是不同的。 见https://gcc.gnu.org/wiki/Cxx11AbiCompatibility
所以不建议混合-std = C ++ 98 -std = C ++编译11库。 跨越图像边界传递数据时可能会崩溃。
(它可能的工作,如果你只叫的extern“C”的功能,并通过仅荚)。
另请参阅相关: 与GCC混合不同的C ++标准