IS C ++的可移植性如何?

时间:2011-10-22 20:21:00

标签: c++ cross-platform

在C ++中,如果我使用Linux编写像pong这样的简单游戏,那么可以在Windows和OSX上编译相同的代码吗?我在哪里可以告诉它无法编译?

5 个答案:

答案 0 :(得分:14)

你有三个主要的可移植性障碍。

第一个也是最简单的是编写所有目标编译器都能理解的C ++代码。注意:这与写入C ++标准不同。 “写入标准”的问题始于:哪个标准?你有C++98, C++03, C++TR1 or C++11 or C++14 or C++17?这些都是对C ++的修订,而你使用较不兼容的编译器的新版本可能是。 C ++非常庞大,实际上你可以期待的最好的是带有一些C ++ 03特性的C ++ 98。

编译器都添加了自己的扩展,并且很容易在不知不觉中使用它们。你最好写标准而不是编译器文档。一些编译器具有“严格”模式,它们将关闭所有扩展。在具有最严格和最佳标准合规性的编译器中进行初级开发是明智的。 gcc-Wstrict系列标志可以启用严格警告。 -ansi将删除与标准冲突的扩展程序。 -std=c++98将告诉编译器违反C ++ 98标准并删除GNU C ++扩展。

考虑到这一点,要保持理智,你必须将自己限制在少数编译器和仅限于他们最近的版本。即使为多个编译器编写一个相对简单的C库也很困难。幸运的是,Linux和OS X都使用gcc。 Windows有Visual C ++,但是在兼容性方面(标准版或彼此版),不同版本更像是一个争吵的家族而不是单个编译器,所以你必须选择一个或两个版本来支持。或者,您可以使用gcc派生的编译器环境之一,例如MinGW。查看[C ++编译器列表](less compliant compilers are likely to be)以获取兼容性信息,但请记住,这仅适用于最新版本。

接下来是您的图形和声音库。它必须不仅仅是跨平台,它必须看起来很好并且在所有平台上都很快。这些天有很多可能性,Simple DirectMedia Layer就是其中之一。您必须选择要编码的级别。你想要详细控制吗?或者你想要引擎来处理事情? There's an existing answer for this所以我不会详细介绍。一定要选择一个致力于跨平台的,而不仅仅是恰好工作。图形库中的兼容性错误可能会使项目快速下沉。

最后,操作系统之间存在简单的不兼容性。 POSIX合规性已经走过了漫长的道路,你很幸运Linux和OS X都是Unix,但Windows永远都是奇怪的人。可能会咬你的东西主要与文件系统有关。这里有一把:

  • 文件系统布局
  • 文件路径语法(即C:\ foo \ bar vs / foo / bar)
  • Mandatory Windows file locking
  • 不同的文件权限系统
  • 不同的进程间通信模型(即fork,共享内存等)
  • 不同的线程模型(您的图形库应该将其平滑)

你有它。真是个烂摊子,对吧?跨平台编程既是一种技巧,也是一种心态和目的陈述。它需要一些奉献精神和额外的时间。你可以采取一些措施来减少这个过程的麻烦......

  • 启用所有限制和警告并修复它们
  • 关闭所有语言扩展程序
  • 在Windows中定期编译和测试,而不仅仅是在最后
  • 获取喜欢Windows项目的程序员
  • 将您自己限制在尽可能少的编译器
  • 选择维护良好,支持良好的图形库
  • 隔离特定于平台的代码(例如,在子类中)
  • 将Windows视为一等公民

最重要的是从头开始。可移植性不是你最后可以解决的问题。不只是你的代码,但如果你不警惕,你的整个设计就会变得不可移植。

答案 1 :(得分:7)

C ++是超便携的,并且可以在更多平台上使用编译器,而不是可以动摇。像Java这样的语言通常被吹捧为大规模跨平台,具有讽刺意味的是它们实际上通常用C ++或C语言实现。

这涵盖了“便携性”。如果你的意思是,跨平台是如何C ++的,那就不那么多:C ++标准只定义一个适合于控制台IO的IO库 - 即基于文本,所以只要你想开发某种GUI,你就需要了使用GUI框架 - GUI框架在历史上非常特定于平台。 Windows现在有多个“原生”GUI框架 - 从Microsoft提供的C ++框架仍然是MFC - 它包装了原生的Win32 API,这是一个C API。 (WPF和WinForms可用于CLR C ++)。

Apple Mac的GUI框架称为Cocoa,是一个Objective-C库,但在该开发环境中很容易从C ++访问Objective C.

在Linux上有GTK +和Qt框架实际上都移植到了Windows和Apple,所以这些C ++框架之一可以解决你的“如何在Windows上构建和运行的C ++编写GUI应用程序,apple mac和linux“。

当然,很难将Qt视为严格的C ++ - Qt为信号和插槽定义了一个特殊的标记,需要预编译编译步骤。

答案 2 :(得分:4)

您可以阅读标准 - 如果程序符合标准,则应该在具有符合C ++标准的编译器的所有平台上进行编译。

对于您可能正在使用的第三方库,平台可用性通常在文档中指定。

当GUI出现问题时,存在跨平台选项(例如QT),但您应该问自己 - 在UI方面我真的想要可移植性吗?有时候,最好让GUI部分特定于平台。

答案 3 :(得分:1)

如果您考虑从Linux移植到Windows,只要不使用任何特定于系统的功能,使用OPENGL作为图形部分就可以自由地在两个操作系统上运行程序。

答案 4 :(得分:-4)

与C相比,C ++的可移植性非常有限,如果不是完全不存在的话。对于一个你不能禁用异常(你可以),因为标准特别指出了未定义的行为。许多设备甚至不支持例外。因此,C ++是ZERO便携式的。再看看UB,它显然是零失效的高性能实时系统,其中异常是禁忌 - 未定义的行为在零失败环境中没有地位。然后是名称重整,大多数(如果不是每个)编译器完全不同。为了良好的便携性和相互兼容性extern" C"必须用于导出符号,但这会使任何和所有命名空间信息完全无效,从而导致重复的符号。可以选择不使用名称空间并使用唯一符号名称。另一个C ++特性呈现无效。然后是语言的复杂性,这导致各种体系结构的各种编译器的实现困难。由于这些困难,真正的便携性成为一个问题。人们可以通过拥有一大串编译器指令/ #ifdefs / mac来解决这个问题。模板?甚至大多数编译器都不支持。

什么便携性?你的意思是几个主流构建目标之间的半可移植性,如Windows的MSVC和Linux的GCC?即便如此,在MAIN-STREAM段中,存在上述所有问题和限制。它甚至认为C ++是可移植的。