开发跨平台 C++11 代码 [关闭]

Posted

技术标签:

【中文标题】开发跨平台 C++11 代码 [关闭]【英文标题】:Developing cross-platform C++11 code [closed] 【发布时间】:2012-01-14 12:21:13 【问题描述】:

使用 C++03,可以(现在仍然)使用 MSVC 和 GCC 编写跨平台代码,在 Windows、Linux 和 Mac OS X 之间共享 C++ 代码库。

现在,C++11 的情况如何?似乎不同的 C++ 编译器实现了 C++11 的不同特性。要构建跨平台的 C++11 代码,将 MSVC10(VS2010)作为一种“最小公分母”是否安全?即,如果我们将批准的 C++11 功能限制为由 MSVC10 实现的功能,那么生成的 C++11 代码是否可以用 GCC 编译(因此可以在 Linux 和 Mac OS X 上使用)?

如果我们需要跨平台代码,还是等待 C++11 编译器成熟并坚持使用 C++03 更好?

谢谢。

【问题讨论】:

我知道您期望得到什么样的答案。使用所有编译器支持的特性,不要使用它们不支持的特性。这不是特定于 C++11,每次出现新标准时都会发生。或者,在任何地方都使用相同的编译器,而不必为此担心。 没有编译器支持所有 C++11,所以简短的回答是,你根本做不到。 【参考方案1】:

您可以使用 GCC 为 Windows 编译代码。你不需要使用微软的编译器。

如果您现在想轻松使用 C++11 功能,那将是您的最佳解决方案。微软还没有实现很多 C++11,而且也不是所有的都计划在 VS11 中。

否则,是的,您显然可以只使用代表最低公分母的编译器实现支持的 C++11 功能子集。您需要检查并确保它是 Microsoft 针对所有新功能的编译器,而不仅仅是假设它是。 我不相信 GCC 已经解决了所有问题,并且不能保证他们对所有功能的实现都是完美的,并且与 Microsoft 的 100% 相匹配。编写完全可移植的代码一直很困难。

仅使用 C++03 功能显然是安全的方法,但它不允许您使用 C++11 功能(显然)。重要的是只有你才能做出的决定。

【讨论】:

这并不难,但你必须抽象出平台差异。保持 C++ 应用程序跨平台是非常易于管理的。当然,如果你进入 C++2011 领域,你的编译器需要支持它。 @piotr:是的,我说的不是跨平台代码。我说的是可以在任何编译器上编译的可移植代码。你不能抽象出你的编译器不支持的特性。【参考方案2】:

C++11 还没有为黄金时间做好准备,正如您已经知道的那样。

不仅解析阶段仍在由各种编译器完成,而且还有一些问题,虽然看起来接受某些功能,但在您当前拥有的版本中可能存在怪癖和错误。

我能想到的唯一合理的方法是首先选择您要使用的编译器:

您可以在 Windows 上使用 gcc/Clang(使用 libstdc++),但这会阻止您与 VC++ 编译的库进行交互 另一方面,您可以针对 gcc/Clang 和 VC++ 验证您的代码(如果需要,还可以验证其他代码)

一旦确定了要使用的编译器,就必须选择要使用的 C++11 功能,并且这些功能适用于所有这些编译器。

gcc 可能在这里更高级 Clang 没有 lambda,但有移动语义和可变参数模板 VC++是我认为最落后的

并且您需要在所有目标平台上使用所有这些编译器设置测试套件,并特别警惕可能的代码生成问题。我建议在 Linux 上使用 Valgrind 示例,也许在 Windows 上使用 Purify(或等效),因为它们都有助于发现这些运行时问题。

请注意,VC++ 和 g++ 可能有默认接受的非标准扩展,并且还可能基于以前的 C++11 草案对代码的解释。

老实说,对于生产用途,我认为这仍然有点不稳定。

【讨论】:

谢谢。我认为移动语义(可以提高性能)、nullptr、auto 和 lambdas 是 MSVC 和 C++ 都支持的 C++11 的“安全”子集;所以我认为选择这些特性对于生产代码应该是可以的。我不确定新的 C++11 库是如何在两个编译器中实现的(在我看来,从语言的角度来看,MSVC 落后于 GCC,但对于库来说状况良好)。 @Mr_C64:实际上,Clang 还不支持 lambda。另外,我不知道 3 个编译器中的任何一个中的线程支持如何(以及 std::atomic<> 票价如何),当然它只涉及多线程代码:)【参考方案3】:

如果你正在编写新代码,你可能不会在明天发布它。

所以要计划好你的发布日期。有一些特性会比其他特性更慢地被接受。主要是难以实现的功能和重复的功能(例如 for 循环的范围)。

我不会太担心使用新的库功能,所有编译器都已经很好地支持了这些功能。

目前没有任何最不重要的共同点,因为微软决定首先专注于库,而其余的则(大部分)用于语言功能。

【讨论】:

【参考方案4】:

这在很大程度上取决于您的项目。如果您只发布二进制文件,则需要确定要使用的工具集并坚持该工具集支持的内容。如果您的团队使用不同的工具,每个人都应该确保他的代码使用通用构建系统(无论是 C++03 还是 C++11)构建。

只要您发布的标头包含的不仅仅是声明,情况就会发生变化。首先,您需要一些基础设施来确定哪个编译器支持什么。您可以自己编写这些测试并将它们与您的构建系统集成,也可以坚持使用Boost.Config。比你可以ifdef 平台相关代码。起初这听起来很简单,但实际上并非如此。每次您拥有可以使用 C++03 变通方案实现的 C++11 代码时,您都希望为您的用户提供两个版本(例如,可变参数模板与预处理器)。这会导致重复代码并带来大量维护成本。我通常只包含 C++11 代码,如果它比解决方法有明显的好处(更好的编译器错误消息(可变参数模板与宏),更好的性能(移动语义))。

【讨论】:

【参考方案5】:

Visual Studio 对 C++2011 的支持非常好,因此如果您使用 GCC 4.7 和 VS2010,您将能够在跨平台的同时使用 C++2011 的大量最有趣的功能。

VC10 和 VC11 对 C++11 的支持概述 http://blogs.msdn.com/b/vcblog/archive/2011/09/12/10209291.aspx

所有编译器的表格: https://wiki.apache.org/stdcxx/C++0xCompilerSupport

GCC C++11 支持: http://gcc.gnu.org/projects/cxx0x.html

还相关:C++11 features in Visual Studio 2012

【讨论】:

【参考方案6】:

目前仅使用 C++11 的那些以某种方式改进代码的特性。 让我解释一下,我不会查找 C++11 特性来使用它们,而是在它们解决我的问题时采用它们。 (这是我了解它们的方式,全部在 SO 上)这种方法将来会改变,但现在我正在这样做。

我目前只使用 c++11 的少数功能,这些功能在 VS2010 和 GCC 中都可以使用。 另外,如果有一个很棒的功能,你想使用,而 VS 没有它,为什么不使用 GCC。它是跨平台的,因此也可以在 Windows 上运行。

【讨论】:

以上是关于开发跨平台 C++11 代码 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C++11多线程

C# 或 Unity 用于跨平台软件开发。需要建议[关闭]

哪个跨移动平台应用程序和 UI 框架? [关闭]

iOS / Android 跨平台开发 [关闭]

为 Phonegap/Titanium 跨平台开发选择硬件 [关闭]

C#使用while循环将项添加到List [关闭]