我们需要用c++11重新编译库吗
do we need to recompile libraries with c++11?
这是一个非常不知情的问题,但是:
我想开始使用C++11。我可以继续使用我用旧的gcc 4.2.1编译器编译的大量库吗?还是需要用新的编译器重新编译它们?我想(或希望)答案是否定的,但我只是一个涉猎者。
这样我至少可以消除一部分无知,你能解释一下为什么会出现这种情况吗?
感谢
是的,你应该这样做。
较弱的原因不是二进制兼容性,问题在于预期。一个支持C++11的编译器将期望有许多可用的功能(在其中移动构造函数),并在适当的时候使用它们。这只是冰山一角,还有其他几个不兼容之处(auto
、0
及其与指针的交互…)
这意味着,根据C++11标准,头中的任何内联方法都可能突然被不同地解释。
更有力的原因是每个版本的编译器都有自己的标准库实现。你真的不想开始混合各种版本,尤其是当它们经历了如此重大的变化时(再次,右值引用…)。
相信我,现在重新编译更简单,而不是一直认为出现的每个错误都可能是由于新旧库之间的不兼容。。。
这是一个编译器问题。例如,如果您有一个同时支持C++03
和C++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++特定功能。
这意味着:
-
您的库不提供类/类模板/函数模板/其他C++特定的东西。
-
您不接受C++类到库函数或从库函数返回C++类。
-
不能通过引用传递函数参数。
-
您不提供带有C++特定实现的公共内联函数。
-
您不会从函数中抛出异常。
-
您没有(因为您没有理由)在公共头文件中包含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错误的好机会,否则由于二进制不兼容,这些错误通常无法修复)。
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- 如何编译:Mac上的Synergy(2017年的新工具链)
- 如何编译和运行一个新的 C++ Actor 框架项目?
- C++编译新的警告过滤器
- 每次都构建(make)lib,只有在lib较新时才重新编译项目
- 如何创建指向派生类的新指针,该派生类在C++编译时未知
- 如何在不退出和失去断点的情况下重新加载重新编译的二进制文件
- 在编译时将整数和分数部分宏组合成一个新的宏或双精度
- C++运算符新重载、编译错误
- 在新OSX上编译旧碳应用
- 为什么G 5.4不能编译此编译时质数代码
- 代码块在尝试编译或创建新文件时出现"An assertion failed!"错误
- 在新的Visual Studio项目中包含任何Eigen 3.3.1文件将无法编译
- RCpp:如何在不重新启动R的情况下重新加载重新编译的C++代码
- 新安装的MinGW问题与编译和可执行文件
- 为什么要编译?(编译是否忽略未包含的 h 文件?
- 高级C和C++编译:无法编译书中提到的示例程序
- 在不同的编译单元中使用不同的编译标志编译相同的头
- 在cygwin中编译新的mingw二进制文件
- 使用boost库编译预编译头文件需要很长时间