我们需要用c++11重新编译库吗

do we need to recompile libraries with c++11?

本文关键字:编译 新编译 c++11 我们      更新时间:2023-10-16

这是一个非常不知情的问题,但是:

我想开始使用C++11。我可以继续使用我用旧的gcc 4.2.1编译器编译的大量库吗?还是需要用新的编译器重新编译它们?我想(或希望)答案是否定的,但我只是一个涉猎者。

这样我至少可以消除一部分无知,你能解释一下为什么会出现这种情况吗?

感谢

是的,你应该这样做。

较弱的原因不是二进制兼容性,问题在于预期。一个支持C++11的编译器将期望有许多可用的功能(在其中移动构造函数),并在适当的时候使用它们。这只是冰山一角,还有其他几个不兼容之处(auto0及其与指针的交互…)

这意味着,根据C++11标准,头中的任何内联方法都可能突然被不同地解释。

更有力的原因是每个版本的编译器都有自己的标准库实现。你真的不想开始混合各种版本,尤其是当它们经历了如此重大的变化时(再次,右值引用…)。

相信我,现在重新编译更简单,而不是一直认为出现的每个错误都可能是由于新旧库之间的不兼容。。。

这是一个编译器问题。例如,如果您有一个同时支持C++03C++11的编译器,这取决于编译器开关,那么您很可能会混合库。在C++11中,没有什么新的强制与C++03不兼容。

但是,您提到您的库是用GGC4.2.1编译的。由于C++11在当时只是一个想法,所以GCC在当时的实现方式很可能与C++11不兼容。

例如,std::list::size()在C++11中必须是O(1),但在C++03中可以是O(N)。GCC当时选择了O(N)实现,不知道未来的需求。当前的GCC std::list::size实现与C++11和C++03都兼容,因为O(1)比O(N)好。

答案完全取决于库的API及其实现依赖关系。

保证您不需要重新编译的条件是:

--您的库在其公共API中没有使用C++特定功能。

这意味着:

  1. 您的库不提供类/类模板/函数模板/其他C++特定的东西。

  2. 您不接受C++类到库函数或从库函数返回C++类。

  3. 不能通过引用传递函数参数。

  4. 您不提供带有C++特定实现的公共内联函数。

  5. 您不会从函数中抛出异常。

  6. 您没有(因为您没有理由)在公共头文件中包含C++特定的库头文件。(如果你确实包含了它们,那不会有什么坏处,但如果你删除了这些包含,一切都会好起来的。这就像一个指示器。)

--您的库仅依赖于与新构建环境中可用的库二进制兼容的库。

如果不满足这些条件,则无法保证您的库能够正常工作。在大多数情况下,重新编译要比确保一切正常工作容易得多。

无论哪种方式,如果您要制作满足上述条件的二进制兼容API,那么设计和实现C语言API要好得多。通过这种方式,您可以自动满足上述条件,并且不会陷入编写C风格C++代码的罪恶。

您可以在不重新编译的情况下使用C++11的大部分(假设ABI兼容),但对我来说,一个特别重要的部分,至少对于已经编译的代码移动语义是无法访问的。

只需使用C++11编译器(最好是C++11 stdlib)重新编译,Move语义就可以使代码更快。

还有其他原因。也许自上次编译以来,您喜欢的库已经具有C++11意识,如果使用C++11编译器编译,现在会更高效、更安全或更容易使用?

对于您自己的库,使用C++11,您肯定可以使其更高效、更安全、更易于使用?:)

如果编译代码的接口使用任何由C++11修改的模板,那么是的,您必须重新编译。否则,您可能可以继续使用旧库(除非编译器提供商也决定同时更改ABI,因为这是修复长期存在的ABI错误的好机会,否则由于二进制不兼容,这些错误通常无法修复)。