6

我正在使用 g++ 4.4 在 linux 上编译一个共享库。如果可以的话,我想在库中使用一些 C++11 功能,但我无法更新编译器的版本,也无法为我的库的用户提供任何特殊的编译器开关。

我有两个问题,我很难找到一个明确的答案。

  1. 如果我用 -std=c++0x 或 -std=g++0x 编译共享库,我是否保证使用我的库的程序不需要这些开关(前提是我在头文件)?它似乎有效,但我不想为未来的微妙问题而注册。

  2. g++ 4.4 中的 C++11 标准库是相当不完整的。由于大部分标准库都是仅头文件,并且 gnu 的头文件通常充满版本 ifdefs,我认为可能有一种方法可以使用 libstdc++ 中至少头文件的更新版本。不过,我不能为它使用不同的 .so 。我敢肯定我可以把它拼凑在一起,但是有可能正确地做这样的事情吗?

谢谢。

4

2 回答 2

5

1. 如果我用 -std=c++0x 或 -std=g++0x 编译共享库,我是否保证使用我的库的程序不需要这些开关(前提是我没有 c++0x头文件中的功能)?它似乎有效,但我不想为未来的微妙问题而注册。

C++11 支持在 GCC 4.x 版本中仍然是实验性的(从 GCC 5 开始不再是实验性的)。尽管我们试图保持工作正常,但答案是否定的,您通常不能保证在所有情况下都能正常工作。使用导致的许多 ABI 更改-std=c++0x可能会导致混合 C++03 代码和 C++11 代码的程序出现问题,有关更多详细信息,请参阅http://gcc.gnu.org/wiki/Cxx11AbiCompatibility。如果您的库没有导出该页面上描述的任何符号,那么您应该没问题。

2.g++ 4.4中C++11的标准库相当不完整。由于大部分标准库都是仅头文件,并且 gnu 的头文件通常充满版本 ifdefs,我认为可能有一种方法可以使用 libstdc++ 中至少头文件的更新版本。不过,我不能为它使用不同的 .so 。我敢肯定我可以把它拼凑在一起,但是有可能正确地做这样的事情吗?

不,绝对没有任何可能会奏效。更高版本的标头使用 4.4 不支持的功能,即使您可以使用它们,您也需要使用较新的libstdc++.so. 就是不行。

标头中没有完整的版本,几乎您会发现只有在使用时由 G++ 定义的#ifdefs检查,但这并不意味着您的 4.4 版本支持 lambda、非静态数据成员初始化器、正确的右值引用语义,默认/删除的函数等,以后的标头可以自由使用。您必须将 libstdc++ 标头与它们随附的相同版本的 GCC 一起使用。__GXX_EXPERIMENTAL_CXX0X__-std=c++0x

简而言之,如果您想要适当的 C++11 支持,您需要使用更新的编译器。

如果您不能使用较新的编译器,则无法获得适当的 C++11 支持。

于 2012-11-14T19:26:15.193 回答
3

我不会尝试这个。只需在头文件中使用一个 C++11 定义的宏来更改类或函数的定义,您的最终用户将违反单一定义规则。我想这些用途可能非常微妙。

然后在类似的说明vector(count, item = T())中,C++11 中不再存在构造函数(现在是两个构造函数)。

简而言之,您必须非常小心您在库中使用的标准库组件,以避免违反单一定义规则,而且我无法想象损坏的风险值得使用这些功能。

可以做的是使用boosttr1填补语言空白,直到您可以使用新的编译器和/或被允许要求您的最终用户使用 C++11 支持进行编译。

于 2012-11-14T16:56:19.467 回答