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

时间:2012-02-23 07:13:38

标签: c++ c++11 backwards-compatibility recompile

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

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

这样我至少可以删除部分无知,你能解释一下为什么会这样吗?

由于

5 个答案:

答案 0 :(得分:9)

是的,你应该。

较弱的原因不是二元兼容性,问题是关于期望。启用C ++ 11的编译器可以使用许多功能(在其中移动构造函数)并在适当时使用它们。这只是冰山一角,还有其他一些不兼容性(auto0及其与指针的互动......)。

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

更强的原因是每个版本的编译器都带有自己的标准库实现。你真的不想开始混合各种版本,特别是当它们经历了这样的重大变化时(再一次,rvalue引用......)。

相信我,现在重新编译更简单,而不是让人觉得每个出现的错误都可能是由于新旧库之间的不兼容而引起的......

答案 1 :(得分:3)

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

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

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

这意味着:

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

  2. 您不接受/返回库函数的C ++类。

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

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

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

  6. 您没有(因为您没有理由)在公共标头中包含C ++特定的库标头。 (如果你把它们包括起来就不会受到伤害,但是如果你删除这些包含的话,一切都会好的。它就像一个指示器。)

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

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

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

答案 2 :(得分:3)

这是一个编译问题。例如,如果您有一个支持C++03C++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)实现,不知道未来的要求。当前的GCC std::list::size实现与C ++ 11和C ++ 03兼容,因为O(1)优于O(N)。

答案 3 :(得分:1)

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

通过使用C ++ 11编译器(最好是C ++ 11 stdlib)重新编译,移动语义可以使代码更快。

还有其他原因。也许你的首选库自上次编译以来已经成为C ++ 11,如果使用C ++ 11编译器编译,它现在更高效,更安全或更容易使用?

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

答案 4 :(得分:1)

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