C++ 的可移植性如何?

发布于 2024-12-11 09:19:36 字数 88 浏览 0 评论 0原文

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

In C++, if I write a simple game like pong using Linux, can that same code be compiled on Windows and OSX? Where can I tell it won't be able to be compiled?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

深陷 2024-12-18 09:19:36

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

第一个也是最简单的方法是编写所有目标编译器都能理解的 C++ 代码。注意:这与按照 C++ 标准编写不同。 “按照标准编写”的问题始于:哪个标准?您有 C++98、C++03、 C++TR1 或 C++11 或 C++14 或 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++ 编译器列表](不太合规的编译器可能会be)以获取兼容性信息,但请记住,这仅适用于最新版本。

接下来是您的图形和声音库。它不仅必须是跨平台的,而且必须在所有平台上看起来都不错并且速度很快。如今有很多可能性,简单的 DirectMedia Layer 就是其中之一。您必须选择要编码的级别。您想要详细的控制吗?或者你想要一个引擎来处理事情吗? 这个问题已有答案,所以我不会详细介绍。一定要选择一款致力于跨平台的产品,而不仅仅是碰巧可以工作。图形库中的兼容性错误可能会导致您的项目快速崩溃。

最后,操作系统之间存在简单的不兼容性。 POSIX 合规性已经取得了长足的进步,幸运的是,Linux 和 OS X 底层都是 Unix,但 Windows 永远是个奇怪的人。可能会困扰你的事情大多与文件系统有关。这里有一些:

  • 文件系统布局
  • 文件路径语法(即 C:\foo\bar 与 /foo/bar)
  • 强制 Windows 文件锁定
  • 不同的文件权限系统
  • 不同的进程间通信模型(即 fork、共享内存等...)
  • 不同线程模型(你的图形库应该解决这个问题)

现在你已经有了它。多么混乱啊?跨平台编程既是一种技术,也是一种心态和目的陈述。这需要一些奉献精神和额外的时间。您可以采取一些措施来减少过程的繁琐...

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

最重要的是这一切都从开始。可移植性并不是你最后才强加的东西。如果您不保持警惕,不仅您的代码,而且您的整个设计都可能变得不可移植。

You have three major portability hurdles.

The first, and simplest, is writing C++ code that all the target compilers understand. Note: this is different from writing to the C++ standard. The problem with "writing to the standard" starts with: which standard? You have C++98, C++03, C++TR1 or C++11 or C++14 or C++17? These are all revisions to C++ and the newer one you use the less compliant compilers are likely to be. C++ is very large, and realistically the best you can hope for is C++98 with some C++03 features.

Compilers all add their own extensions, and it's all too easy to unknowingly use them. You would be wise to write to the standard and not to the compiler documentation. Some compilers have a "strict" mode where they will turn off all extensions. You would be wise to do primary development in the compiler which has the most strictures and the best standard compliance. gcc has the -Wstrict family of flags to turn on strict warnings. -ansi will remove extensions which conflict with the standard. -std=c++98 will tell the compiler to work against the C++98 standard and remove GNU C++ extensions.

With that in mind, to remain sane you must restrict yourself to a handful of compilers and only their recent versions. Even writing a relatively simple C library for multiple compilers is difficult. Fortunately, both Linux and OS X use gcc. Windows has Visual C++, but different versions are more like a squabbling family than a single compiler when it comes to compatibility (with the standard or each other), so you'll have to pick a version or two to support. Alternatively, you can use one of the gcc derived compiler environments such as MinGW. Check the [list of C++ compilers](less compliant compilers are likely to be) for compatibility information, but keep in mind this is only for the latest version.

Next is your graphics and sound library. It has to not just be cross platform, it has to look good and be fast on all platforms. These days there's a lot of possibilities, Simple DirectMedia Layer is one. You'll have to choose at what level you want to code. Do you want detailed control? Or do you want an engine to take care of things? There's an existing answer for this so I won't go into details. Be sure to choose one that is dedicated to being cross platform, not just happens to work. Compatibility bugs in your graphics library can sink your project fast.

Finally, there's the simple incompatibilities which exist between the operating systems. POSIX compliance has come a long way, and you're lucky that both Linux and OS X are Unix under the hood, but Windows will always be the odd man out. Things which are likely to bite you mostly have to do with the filesystem. Here's a handful:

  • Filesystem layout
  • File path syntax (ie. C:\foo\bar vs /foo/bar)
  • Mandatory Windows file locking
  • Differing file permissions systems
  • Differing models of interprocess communication (ie. fork, shared memory, etc...)
  • Differing threading models (your graphics library should smooth this out)

There you have it. What a mess, huh? Cross-platform programming is as much a state of mind and statement of purpose as it is a technique. It requires some dedication and extra time. There are some things you can do to make the process less grueling...

  • Turn on all strictures and warnings and fix them
  • Turn off all language extensions
  • Periodically compile and test in Windows, not just at the end
  • Get programmer who likes Windows on the project
  • Restrict yourself to as few compilers as you can
  • Choose a well maintained, well supported graphics library
  • Isolate platform specific code (for example, in a subclass)
  • Treat Windows as a first class citizen

The most important thing is to do this all from the start. Portability is not something you bolt on at the end. Not just your code, but your whole design can become unportable if you're not vigilant.

智商已欠费 2024-12-18 09:19:36

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++ 框架之一可以解决您的“如何用 C++ 编写一个在 Windows、Apple Mac 和 Linux 上构建和运行的 GUI 应用程序” 。

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

C++ is ultra portable and has compilers available on more platforms than you can shake a stick at. Languages like Java are typically touted as being massively cross platform, ironically they are in fact usually implemented in C++, or C.

That covers "portability". If you actually mean, how cross platform is C++, then not so much: The C++ standard only defines an IO library suitable for console IO - i.e. text based, so as soon as you want develop some kind of GUI, you are going to need to use a GUI framework - and GUI frameworks are historically very platform specific. Windows has multiple "native" GUI frameworks now - the C++ framework made available from Microsoft is still MFC - which wraps the native Win32 API which is a C API. (WPF and WinForms are available to CLR C++).

The Apple Mac's GUI framework is called Cocoa, and is an objective-C library, but its easy to access Objective C from C++ in that development environment.

On Linux there is the GTK+ and Qt frameworks that are both actually ported to Windows and Apple, so one of these C++ frameworks can solve your "how to write a GUI application in C++ once that builds and runs on windows, apple mac and linux".

Of course, its difficult to regard Qt as strictly C++ anymore - Qt defines a special markup for signals and slots that requires a pre-compile compile step.

睡美人的小仙女 2024-12-18 09:19:36

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

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

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

You can read the standard - if a program respects the standard, it should be compilable on all platforms that have a C++ standard-compliant compiler.

As for 3rd party libraries you might be using, the platform availability is usually specified in the documentation.

When GUI comes to question, there are cross-platform options (such as QT), but you should probably ask yourself - do I really want portability when it comes to UI? Sometimes, it's better to have the GUI part platform-specific.

风蛊 2024-12-18 09:19:36

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

If you are thinking of porting from Linux to Windows, using OPENGL for the graphical part gives you freedom to run your program on both operating systems as long as you don't use any system specific functionality.

时光沙漏 2024-12-18 09:19:36

与 C 相比,C++ 的可移植性即使不是完全不存在,也是极其有限的。对于一个你不能禁用异常的人(你可以),因为标准明确指出这是未定义的行为。许多设备甚至不支持例外。因此,C++ 是零可移植的。再加上 UB,显然对于零故障高性能实时系统来说这是不行的,在这种系统中,异常是禁忌——未定义的行为在零故障环境中没有立足之地。然后是名称修改,大多数(如果不是每个)编译器都会做完全不同的事情。为了获得良好的可移植性和相互兼容性,必须使用 extern“C” 来导出符号,但这会使任何和所有名称空间信息完全无效,从而导致重复的符号。人们当然可以选择不使用命名空间并使用唯一的符号名称。又一个 C++ 功能失效了。然后是语言的复杂性,这导致了不同架构的不同编译器的实现困难。由于这些困难,真正的可移植性成为一个问题。人们可以通过一大串编译器指令/#ifdefs/宏来解决这个问题。模板?大多数编译器甚至不支持。

什么便携性?您是指几个主流构建目标(例如 Windows 的 MSVC 和 Linux 的 GCC)之间的半可移植性?即使在那里,在主流部分,所有上述问题和限制都存在。认为 C++ 是可移植的就太弱智了。

Compared to C, C++ portability is extremely limited, if not completely unexisting. For one you can't disable exceptions (well you can), for the standard specifically says that's undefined behaviour. Many devices don't even support exceptions. So as for that, C++ is ZERO portable. Plus seeing the UB, it's obvioulsy a no-go for zero-fail high-performance real time systems in which exceptions are taboo - undefined behaviour has no place in zero-fail environment. Then there's the name mangling which most, if not every, compiler does completely different. For good portability and inter-compatibility extern "C" would have to be used to export symbols, yet this renders any and all namespace information completely void, resulting in duplicate symbols. One can ofcourse choose to not use namespaces and use unique symbol names. Yet another C++ feature rendered void. Then there's the complexity of the language, which results in implementation difficulties in the various compilers for various architectures. Due to these difficulties, true portability becomes a problem. One can solve this by having a large chain of compiler directives/#ifdefs/macros. Templates? Not even supported by most compilers.

What portability? You mean the semi-portability between a couple of main-stream build targets like MSVC for Windows and GCC for Linux? Even there, in that MAIN-STREAM segment, all the above problems and limitations exist. It's retarded to even think C++ is portable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文