g++ -std=c++0x 和兼容性

6
我正在使用g++ 4.4在Linux上编译一个共享库。我希望在库中使用一些C++11特性,但不能更新编译器版本或要求用户为我的库使用特殊编译器开关。
我有两个问题,但很难找到确定的答案。 1. 如果我使用-std=c++0x或-std=g++0x编译共享库,假设我的头文件中没有c++0x功能,那么我是否保证使用我的库的程序不需要这些开关?看起来是可以的,但我不想以后遇到微妙的问题。 2. g++ 4.4的C++11标准库非常不完整。由于许多标准库只是头文件,并且gnu的头文件通常充满了版本ifdefs,因此我认为可能有一种方法可以在libstdc++中使用至少更高版本的头文件。尽管不能使用不同的.so进行操作。我相信我可以将其组合在一起,但是否可能正确地做到这一点?
谢谢。

关于第二点,您能否更新到较新版本的g++?根据http://gcc.gnu.org/projects/cxx0x.html显示,4.8版本具有更完整的支持。 - Xymostech
我很想这样做,但不幸的是在这个环境下我不能这么做。 - user1806566
可能相关的问题... - Kerrek SB
@Xymostech,4.8版本甚至还没有发布,可能要等4-6个月才会发布。 - Jonathan Wakely
2个回答

5
如果我使用-std=c++0x或-std=g++0x编译共享库,是否保证使用我的库的程序不需要这些开关(前提是头文件中没有c++0x特性)?看起来可以工作,但我不想在以后遇到微妙的问题。 GCC 4.x版本中仍处于实验阶段的C++11支持(从GCC 5开始不再是实验性的)。虽然我们尽力让事情正常运行,但一般而言,你不能保证所有情况下都能正常工作。使用-std=c++0x会导致一些ABI更改,可能会对混合使用C++03代码和C++11代码的程序造成问题,请参见http://gcc.gnu.org/wiki/Cxx11AbiCompatibility以获取更多详细信息。如果你的库没有导出该页面上描述的任何符号,则应该没问题。

2. 在g++ 4.4中,C++11的标准库相当不完整。由于许多标准库只是头文件,并且gnu的头文件通常充满了版本ifdefs,我认为可能有一种方法可以使用libstdc++中至少较新版本的头文件。但我不能为它使用不同的.so文件。我确定我可以将其拼凑在一起,但是否可能正确地执行此类操作?

不,绝对没有任何机会能够成功。较新版本的头文件使用不受4.4支持的功能,即使您可以使用它们,也需要使用更新的libstdc++.so。不行。

头文件中 没有 充满版本 #ifdefs,几乎唯一的检查是对 __GXX_EXPERIMENTAL_CXX0X__ 的检查,这是由 G++ 在使用 -std=c++0x 时定义的,但这并不意味着您的 4.4 版本支持 lambda、非静态数据成员初始化、正确的右值引用语义、默认/删除函数等后来的标头都广泛使用。您 必须 使用与 GCC 相同版本的 libstdc++ 标头。
简而言之,如果您想要正确的 C++11 支持,则需要使用更新的编译器。
如果您无法使用更新的编译器,则无法获得适当的 C++11 支持。

谢谢解释。我想现在我得等待新功能了。 - user1806566
现在是否仍然如此?换句话说,我在哪些情况下可以在GCC中混合使用c++98/03库和c++11库? - André
@Andre 我稍微更新了答案。我给出的维基链接仍然有效。通常情况下,使用GCC 5+,您可以混合编译任何-std选项的代码,请参阅维基页面以了解该规则的例外情况。 - Jonathan Wakely

3
我不建议这样做。只要头文件中有一个C++11定义的宏改变了类或函数的定义,你的终端用户就会违反一个定义规则。我想这些用法可能非常微妙。
另外,还有一个类似的问题,就是在C++11中已经不存在vector(count, item = T())构造函数(现在是两个构造函数)。
简而言之,你必须非常小心地选择标准库组件,以避免违反一个定义规则,我无法想象冒险使用这些特性的风险是否值得。
你可以使用boost和tr1来填补语言差距,直到你能够使用新的编译器和/或被允许要求你的最终用户编译支持C++11。

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