c++的可移植性如何?

How portable IS C++?

本文关键字:可移植性 c++      更新时间:2023-10-16

在c++中,如果我在Linux上编写一个简单的游戏,比如pong,那么同样的代码可以在Windows和OSX上编译吗?我在哪里可以知道它不能被编译?

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

第一个,也是最简单的,是编写所有目标编译器都能理解的c++代码。注意:这与编写c++标准是不同的。"按照标准编写"的问题始于:哪个标准?你有c++ 98, c++ 03, c++ TR1或者c++ 11或者c++ 14或者c++ 17?这些都是c++的修订版,您使用的版本越新,编译器的兼容性可能越低。c++是非常大的,实际上你能期望的最好的是c++ 98加上一些c++ 03的特性。

编译器都会添加它们自己的扩展名,而且很容易在不知情的情况下使用它们。明智的做法是编写标准,而不是编写编译器文档。一些编译器有一个"严格"模式,他们会关闭所有扩展。明智的做法是在具有最多限制和最佳标准遵从性的编译器中进行初级开发。gcc具有-Wstrict系列标志,用于打开严格警告。-ansi将删除与标准冲突的扩展。-std=c++98将告诉编译器针对c++ 98标准工作,并删除GNU c++扩展。

考虑到这一点,为了保持理智,您必须限制自己使用少数几个编译器,并且只使用它们的最新版本。即使为多个编译器编写一个相对简单的C库也是困难的。幸运的是,Linux和OS X都使用gcc。Windows有Visual c++,但是不同的版本更像是一个争吵不休的家庭,而不是一个单一的编译器,当涉及到兼容性(与标准或彼此),所以你必须选择一个或两个版本来支持。或者,您可以使用gcc派生的编译器环境之一,例如MinGW。查看[c++编译器列表](可能不太兼容的编译器)以获取兼容性信息,但请记住这仅适用于最新版本。

接下来是你的图形和声音库。它不仅要跨平台,还必须在所有平台上看起来都很好,运行速度也很快。现在有很多可能性,简单的DirectMedia层就是其中之一。您必须选择在什么级别上进行编码。你想要详细控制吗?还是你想要一个引擎来处理这些事情?这个问题已经有了答案,所以我就不详细讲了。一定要选择一款致力于跨平台的游戏,而不是碰巧有效的游戏。你的图形库中的兼容性错误会让你的项目很快陷入困境。

最后,操作系统之间存在简单的不兼容性。POSIX的遵从性已经走过了很长的路,你很幸运,Linux和OS X都是Unix的底层,但Windows将永远是一个奇怪的人。最可能困扰您的事情往往与文件系统有关。这里有一些:

    <
  • 文件系统布局/gh>
  • 文件路径语法(即。C:foobar vs/foo/bar)
  • 强制Windows文件锁定
  • 不同的文件权限系统
  • 不同的进程间通信模型(例如;fork,共享内存等)
  • 不同的线程模型(你的图形库应该平滑这一点)

你知道了。真是一团糟,是吧?跨平台编程既是一种技术,也是一种思想状态和目的宣言。这需要一些奉献精神和额外的时间。你可以做一些事情来让这个过程不那么折磨人。

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

最重要的是从头开始。可移植性不是你最后才安装的东西。如果你不够警惕,不仅是你的代码,甚至你的整个设计都可能变得不可移植。

c++具有超强的可移植性,并且在许多平台上都可以使用编译器。像Java这样的语言通常被吹捧为大规模跨平台,讽刺的是,它们实际上通常是用c++或C实现的。

涵盖了"可移植性"。如果你真的想知道c++的跨平台程度,那就没那么多了:c++标准只定义了一个适合控制台IO的IO库——也就是基于文本的IO库,所以一旦你想开发某种GUI,你就需要使用GUI框架——而GUI框架在历史上是非常特定于平台的。Windows现在有多个"本地"GUI框架——微软提供的c++框架仍然是MFC——它封装了本地Win32 API,这是一个C API。(WPF和WinForms可用于CLR c++)。

苹果Mac的GUI框架叫做Cocoa,它是一个Objective -C库,但是在这个开发环境中从c++访问Objective -C很容易。

在Linux上,GTK+和Qt框架实际上都移植到Windows和Apple上,所以这些c++框架中的一个可以解决你的"如何用c++编写GUI应用程序,一旦在Windows, Apple mac和Linux上构建和运行"。

当然,很难再把Qt严格地看作c++了——Qt为信号和插槽定义了一个特殊的标记,这需要一个预编译编译步骤。

您可以阅读标准-如果一个程序遵循标准,它应该可以在所有具有c++标准兼容编译器的平台上编译。

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

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

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

与C相比,c++的可移植性非常有限,如果不是完全不存在的话。首先,你不能禁用异常(你可以),因为标准明确规定这是未定义的行为。许多设备甚至不支持异常。因此,c++的可移植性为零。再加上看到UB,它显然是零失败高性能实时系统的禁忌,异常是禁忌-未定义的行为在零失败环境中没有位置。然后是名称混淆,大多数(如果不是每个)编译器做的都完全不同。为了获得良好的可移植性和相互兼容性,必须使用外部"C"来导出符号,但这会使所有名称空间信息完全无效,从而导致重复的符号。当然可以选择不使用名称空间,而使用唯一的符号名称。又一个c++特性无效了。然后是语言的复杂性,这导致在各种体系结构的各种编译器中实现困难。由于这些困难,真正的可移植性成为一个问题。我们可以通过大量编译器指令/#ifdefs/宏来解决这个问题。模板吗?大多数编译器都不支持。

可移植性什么?您指的是两个主流构建目标(如Windows的MSVC和Linux的GCC)之间的半可移植性?即使在主流部分,上述所有问题和限制都存在。甚至认为c++是可移植的都是愚蠢的。