这是一个非常无知的问题,但是:
我想开始使用 C++11。我可以继续使用用旧的 gcc 4.2.1 编译器编译的大量库,还是需要用新的编译器重新编译它们?我认为(或希望)答案是否定的,但我只是一个涉足者。
这样我至少可以消除我的部分无知,你能解释一下为什么在这两种情况下?
谢谢
这是一个非常无知的问题,但是:
我想开始使用 C++11。我可以继续使用用旧的 gcc 4.2.1 编译器编译的大量库,还是需要用新的编译器重新编译它们?我认为(或希望)答案是否定的,但我只是一个涉足者。
这样我至少可以消除我的部分无知,你能解释一下为什么在这两种情况下?
谢谢
是的你应该。
较弱的原因不是二进制兼容性,问题在于期望。启用 C++11 的编译器将期望许多功能可用(在它们之间移动构造函数)并在适当时使用它们。这只是冰山一角,还有其他几个不兼容的地方(auto
以及0
它与指针的交互......)。
这意味着根据 C++11 标准,标头中的任何内联方法都可能突然被不同地解释。
更有力的原因是每个版本的编译器都有自己的标准库实现。您真的不想开始混合各种版本,尤其是当它们经历了如此重大的变化时(再一次,右值引用......)。
相信我,现在重新编译更简单,而不是那种烦人的想法,即出现的每个错误都可能是由于新旧库之间的不兼容......
答案完全取决于您的库的 API 及其实现依赖项。
保证您不需要重新编译的条件是:
-- 您的库在其公共 API 中不使用 C++ 特定功能。
这意味着:
您的库不提供类/类模板/函数模板/其他 C++ 特定的东西。
您不接受/返回 C++ 类到/从您的库函数。
您不通过引用传递函数参数。
您不提供具有 C++ 特定实现的公共内联函数。
你不会从你的函数中抛出异常。
您没有(因为您没有理由)在公共标头中包含 C++ 特定的库标头。(如果你确实包含它们不会有什么坏处,但如果你删除这些包含,一切都必须是好的。它就像一个指示器。)
-- 您的库仅依赖于与新构建环境中可用的库二进制兼容的库。
如果不满足这些条件,则无法保证您的库将正常工作。在大多数情况下,重新编译比确保一切正常工作要容易得多。
无论哪种方式,如果您要制作满足上述条件的二进制兼容 API,那么设计和实现 C 语言 API 会好得多。这样您就可以自动满足上述条件,而不会陷入编写 C 风格的 C++ 代码的罪恶之中。
这是一个编译器问题。例如,如果您有一个编译器同时支持C++03
并C++11
依赖于编译器开关,那么您很可能可以混合库。C++11 中没有什么新东西会强制与 C++03 不兼容。
但是,您提到您的库是使用 GGC 4.2.1 编译的。由于当时 C++11 只是一个想法,因此很可能当时的 GCC 是以与 C++11 不兼容的方式实现的。
例如,std::list::size()
在 C++11 中必须是 O(1),但在 C++03 中可能是 O(N)。当时 GCC 选择了 O(N) 实现,不知道未来的需求。当前的 GCCstd::list::size
实现与 C++11 和 C++03 兼容,因为 O(1) 优于 O(N)。
您可以在不重新编译的情况下使用 C++11 的大部分内容(假设 ABI 兼容),但至少对我而言,一个特别重要的部分将无法被已编译的代码访问 - 移动语义。
只需使用 C++11 编译器(最好是 C++11 标准库)重新编译,移动语义就可以使您的代码更快。
还有其他原因。也许您的首选库自从您上次编译它以来已经支持 C++11,并且如果使用 C++11 编译器编译,它现在更高效、更安全或更易于使用?
对于您自己的库,使用 C++11 您肯定可以使其更高效、更安全且更易于使用吗?:)
如果您对已编译代码的接口使用任何由 C++11 修改的模板,那么是的,您必须重新编译。否则,您可能可以继续使用您的旧库(除非编译器提供商也决定同时更改 ABI,因为这是修复长期存在的 ABI 错误的好机会,否则这些错误通常会因为二进制文件而无法修复不兼容)。