不同的GCC方言能够链接在一起吗?

17

我知道原则上这可能是未定义行为,但考虑到处理大型项目的利益,以下是我的GCC相关问题:

假设我使用相同的编译器安装程序,用gcc -std=c++98编译一个翻译单元,用-std=c++11编译另一个翻译单元,那么有没有任何保证我可以将两个目标文件链接在一起并获得一个定义明确的程序?

据我所知,潜在的问题只能来自于不同的宏导致库头文件的不同视图,而这反过来最多只会向标准库类中添加新成员函数,但从不会添加成员对象。

这样是否可以接受使用不同的语言选项编译较大项目的不同部分?

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

3个回答

9
首先,不会影响二进制兼容性。最安全的解决方案是假设所有编译器选项都相同,除非编译器明确说明该选项不会影响二进制兼容性(大多数编译器都缺乏这种文档)。在实践中,如果缺少文档,则似乎可以肯定控制警告的选项(例如g++中的-W...)不会影响二进制兼容性,并且影响代码生成的选项(语言级别等)可能会影响二进制兼容性:g++通常在不同的优化级别之间维护兼容性,而VC++则不会。
另一个真正的问题是在命令行中定义预处理器符号。再次,最安全的选择是所有定义都相同,但也需要一些常识:人们几乎无法指望标准库已经使用了您项目中使用的预处理器符号(例如MYPROG_CONFIG_FILE_LOCATION)。另一方面,请注意,_GLIBCXX_DEBUG_GLIBCXX_DEBUG_PEDANTIC的预处理器定义将影响二进制兼容性(尽管g++确保您将获得与它们一致的库版本,如果您始终如一地使用它们)。
关于您的问题:我不会预计标准版本会对二进制兼容性产生太大影响,但是如果选择以某种方式影响某些预定义的预处理器符号,这可能会破坏库中的二进制兼容性,就像如果您使用_GLIBCXX_DEBUG编译了一些模块,而另一些没有。它可能有效,但我不会指望它。

1
很难期望标准库已经使用了在你的项目中使用的预处理器符号进行编译。即使是这样,假设宏“MYPROG_CONFIG_FILE_LOCATION”在“memset.c”中使用,那么该定义对于“memset.c”的含义与其在您的程序中的含义完全无关。因此,如果使用/不使用“MYPROG_CONFIG_FILE_LOCATION”编译“memset.c”会对二进制兼容性产生影响,那么它将独立于您的程序是否也使用“MYPROG_CONFIG_FILE_LOCATION”。 - Steve Jessop
@SteveJessop 是的。即使真有,也应该对您透明。实际上,您名称空间中的所有预处理器符号(即不以下划线开头,也不包含两个相邻下划线)_应该_是安全的。在实现名称空间中的预处理器符号,如_GLIBCXX_DEBUG,则不安全。 - James Kanze

3
我知道从原则上讲,这可能是未定义的行为。
不是的。
假设我使用相同的编译器安装包分别用gcc -std=c++98-std=c++11编译两个对象文件,是否有任何保证我能够链接两个目标文件并获得一个良定义程序?
是的,这是被支持和可行的(存在一些例外情况,比如在一个对象中启用Debug模式而在另一个对象中未启用,或者在一个对象中使用明确改变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之间在两个方向上都是兼容的。
不是在两个方向上,你需要使用来自GCC 4.6(或更新版本)的libstdc++.so,因为使用那个版本编译的对象可能依赖于在较新版本中引入的并且在旧的libstdc++.so库中不存在的符号。
一些相关信息在https://dev59.com/4lYN5IYBdhLWcg3w4bn1#49119902

0

那个维基页面似乎不是最新的 :-( - Marc Glisse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接