One of the first things I learned as a student was that C++ applications don't run on different operating systems. Recently, I read that Qt based C++ applications run everywhere. So, what is going on? Are C++ applications cross-platform or not?
-
84Only if you write them to be. – Cory Kramer Oct 20 '15 at 13:46
-
2https://programmers.stackexchange.com/questions/281851/what-makes-a-program-cross-platform-or-not – Cory Kramer Oct 20 '15 at 13:46
-
It depends on what you mean by "C++ application". Windows applications, for example, can be written in C++, and they are unlikely to run on any other platform. Qt, WxWidgets, SDL or similiar products might help to create multiplatform application. – Zsigmond Lőrinczy Oct 20 '15 at 15:42
-
108 people think this is well researched. Because portable code is a topic rarely covered in C++ right guys? – Alec Teal Oct 20 '15 at 17:15
-
4It also depends on what you mean by "cross-platform": Code portable (C++ is), and binary portable (C++ is not). – Mooing Duck Oct 20 '15 at 18:10
-
I mean the application, not the language. I read in the Qt official website that C++ applications run everywhere. – nick Oct 20 '15 at 18:20
-
@Ezio, Qt is in the binary compatibility business, so they would say that. They mean if you use the right tools and APIs and runtimes, and you do the right things as a developer, you can make cross-platform deliverables. This has less to do with C++ and more to do with, well, tools, APIs, and runtimes. – Oct 21 '15 at 01:34
-
9The applications are not cross platform, but the code can be. – rhughes Oct 21 '15 at 01:55
-
@Ezio Qt code will be - cross platform issues are resolved by them, if you use their libraries. eg., If you use a Microsoft function to read a file, it will work on Windows but not Linux, if you use the Qt function to read a file, they will have made it work on both platforms. – gbjbaanb Oct 21 '15 at 10:41
6 Answers
Source code compatible. If I compile the source code, will it run everywhere?
API/ABI compatibility. Does the OS provide the interface to its components in a way that the code will understand?
Binary compatibility. Is the code capable of running on the target host?
Source code compatible
C++
is a standard which defines how structures, memory, files can be read and written.
#include <iostream>
int main( int argc, char ** argv )
{
std::cout << "Hello World" << std::endl;
}
Code written to process data (e.g. grep
, awk
, sed
) is generally cross-platform.
When you want to interact with the user, modern operating systems have a GUI, these are not cross-platform, and cause code to be written for a specific platform.
Libraries such as qt
or wxWidgets
have implementations for multiple platforms and allow you to program for qt
instead of Windows
or iOS
, with the result being compatible with both.
The problem with these anonymizing libraries, is they take some of the specific benefits of platform X away in the interest of uniformity across platforms.
Examples of this would be on Windows
using the WaitForMultipleObjects
function, which allows you to wait for different types of events to occur, or the fork
function on UNIX, which allows two copies of your process to be running with significant shared state. In the UI, the forms look and behave slightly different (e.g. color-picker, maximize, minimize, the ability to track mouse outside of your window, the behaviour of gestures).
When the work you need to be done is important to you, then you may end up wanting to write platform specific code to leverage the advantages of the specific application.
The C
library sqlite
is broadly cross-platform code, but its low-level IO is platform specific, so it can make guarantees for database integrity (that the data is really written to disk).
So libraries such as Qt do work, they may produce results which are unsatisfactory, and you end up having to write native code.
API/ABI compatibility
Different releases of UNIX and Windows have some form of compatibility with each other. These allow a binary built for one version of the OS to run on other versions of the OS.
In UNIX the choice of your build machine defines the compatibility. The lowest OS revision you wish to support should be your build machine, and it will produce binaries compatible with subsequent minor versions until they make a breaking change (deprecate a library).
On Windows and Mac OS X, you choose an SDK which allows you to target a set of OS's with the same issues with breaking changes.
On Linux, each kernel revision is ABI incompatible with any other, and kernel modules need to be re-compiled for each kernel revision.
Binary compatibility
This is the ability of the CPU to understand the code. This is more complex than you might think, as the x64 chips, can be capable (depending on OS support) of running x86 code.
Typically a C++ program is packaged inside a container (PE executable, ELF format) which is used by the operating system to unpack the sections of code and data and to load libraries. This makes the final program have both binary (type of code) and API (format of the container) forms of incompatibilities.
Also today if you compile a x86 Windows Application (targeting Windows 7 on Visual Studio 2015), then the code may fail to execute if the processor does not have SSE2 instructions (about 10 years old CPU).
Finally when Apple changed from PowerPC to x86, they provided an emulation layer which allowed the old PowerPC code to run in an emulator on the x86 platform.
So in general binary incompatibility is a murky area. It would be possible to produce an OS which identified invalid instructions (e.g. SSE2) and in the fault, emulated the behaviour, this could be updated as new features come out, and keeps your code running, even though it is binary incompatible.
Even if your platform is incapable of running a form of instruction set, it could be emulated and behave compatibly.
-
"The problem with these anonymizing libraries, is they take some of the specific benefits of platform X away...". What are those benefits you mentioned? Does it make the application slower or even the compilation process different? – nick Oct 20 '15 at 17:31
-
9@Ezio It can make the application "feel" different - some things might be the wrong color, or the wrong font, or spacing is a few pixels off, or it doesn't interact well with drag and drop, or the file open dialog box looks completely different, etc. It can make an appliation "seem cheap". Some libraries are worse about this than others. – Random832 Oct 20 '15 at 18:38
-
More generally, some OSes do things differently from one another. Windows has `%APPDATA%`, My Documents, the user's home folder, etc., while *nix tends to only have the latter by default, and may use dotfiles to implement APPDATA-like behavior. – Kevin Oct 20 '15 at 23:09
-
Hi, can you tell me how then it is possible that one 'exe' file can run on several different computers? – xrisk Oct 21 '15 at 02:01
-
2@Random832 still works better than Java though (which is wrong on every platform :-) ) – gbjbaanb Oct 21 '15 at 10:45
-
1@Random832 Qt's libs are *generally* faithful to the host platform's defaults (button ordering, shadows, transparency, etc.), but there are a few places where something will feel slightly "alien" -- but so far never in ways I've *ever* seen a business customer actually notice (Win/Lin/OSX). This is the price cross-platform in terms of different window-managers, though. It has taken a *long* time to even get to this point. But I honestly can't imagine anyone thinking its a good idea to write a very large system that can only run on one system anymore. (Niche client apps are a different story.) – zxq9 Oct 21 '15 at 13:33
-
Since downvoting requires to add the comment, I'll add one. There is a lot of information overload for junior developers who would like to know if C++ is cross-platform or not. There should be an answer first - no it is not cross platform (the binaries you create are not) and then all the interesting and insightful information you provided for those who need these details and want to understand why. – GuardianX Apr 09 '23 at 23:07
Standard C++ is cross platform in the "write once, compile anywhere" sense, but not in the "compile once, run anywhere" sense.
That means that if you write a program in standard C++, you can compile and then run it on any target environment that has a standard conforming implementation of C++.
You can however not compile your program on your machine, ship the binary and then expect it to work on other targets. (At least not in general. One can of course distribute binaries from C++ code under certain conditions, but those depend on the actual target. This is a broad field.)
Of course, if you use extra, non-standard features like gcc's variable length arrays or third party libraries, you can only compile on systems that provide those extensions and libraries.
Some libraries like Qt and Boost are available on many systems (those two on Linux, Mac and Windows at least I believe), so your code will stay cross platform if you use those.

- 49,044
- 25
- 144
- 182
-
11... and the Standard has no graphical functionality whatsoever (or network, etc.), so in practice it means writing in "Standard C++ plus cross-platform libraries", and then you can compile anywhere that has an implementation of those libraries. – Ben Voigt Oct 20 '15 at 13:50
-
10Even the "compile anywhere" part is not 100% guaranteed. I worked as a teaching assistant for a C++ class once, and one of my fellow TA's was giving failing grades to 90+% of her students. The reason? The students had copied some code from a Word document, at the professor's instruction, which happened to contain m-dashes *in a comment* (because Word just does that sort of thing). When compiled in Windows, they caused no problems, but this TA was using a Linux machine (not sure which compiler), and it refused to compile the same code because of the unrecognized characters. – Darrel Hoffman Oct 20 '15 at 17:26
-
7@DarrelHoffman I think it's the responsibility of the people running the course to ensure that students have access to the same kind of system their code is being graded on. And with it being 90% the TA should have noticed the issue instead of just giving out failing grades. – Random832 Oct 20 '15 at 18:41
-
1@Random832 - I completely agree, which is why I reported the problem to the professor and had him speak with the other TA about what she was doing. The grades were then corrected. The students were in fact *told* to use a specific compiler, and it worked for them because they were using that compiler. The other TA was clearly in the wrong. I was just relaying an anecdote that shows that "compile anywhere" is not necessarily guaranteed. – Darrel Hoffman Oct 20 '15 at 18:46
-
3Maybe you want to also quote the Java mantra "Compile once, debuug everywhere" (I'm not sure whether C# is better or worse.) – Deduplicator Oct 20 '15 at 20:57
-
2
-
5@DarrelHoffman: On the other hand the standard states which characters are allowed in source (basically the ASCII-7 set without backtics, dollar and "at" signs, in native encoding), and that anything beyond that is "implementation-defined". So a source with m-dashes in there is not "standard C++". (Yes I know this is being nitpicky, I *do* think the compiler should have handled that more gracefully, I *do* think the TA should have handled the problem differently, but we're talking about TA failure, not language failure here.) – DevSolar Oct 21 '15 at 07:05
-
"Qt" [coughs theatrically] So, anyway! **gtkmm** is a cross-platform GUI library, with which I can compile my current project on Linux, Windows, and OS X, with identical runtime experiences (down to sharing the theme - not a drawback as many claim, IMO). Plus, it's standard C++14, rather than _C++-plus-different-containers-plus-a-pre-preprocessor_ ;-) I get why they implemented it thusly _way back when_, but as someone who was teaching myself standard C++, GTKmm just made more sense. – underscore_d Apr 15 '16 at 12:19
-
This should be the **real** answer to the question. C++ **is not** cross-platform. If people think that providing compiler for each platform makes the language *cross platform* - well, **most** of the popular languages have compilers on most of the platforms so this question wouldn't even be asked in the first place. – GuardianX Apr 09 '23 at 23:04
You can achieve that your source compiles on various platforms, giving you various binaries from the same source base.
This is not "compile once, run anywhere with an appropriate VM" as Java or C# do it, but "write once, compile anywhere with an appropriate environment" the way C has done it all the time.
Since the standard library does not provide everything you might need, you have to look for third-party libraries to provide that functionality. Certain frameworks -- like Boost, Qt, GTK+, wxWidgets etc. -- can provide that. Since these frameworks are written in a way that they compile on different platforms, you can achieve cross-platform functionality in the aforementioned sense.
There are various things to be aware of if you want your C++ code to be cross-platform.
The obvious thing is source that makes assumption on data types. Your long
might be 32bit here and 64bit there. Data type alignment and struct padding might differ. There are ways to "play it safe" here, like size_t
/ size_type
/ uint16_t
typedefs etc., and ways to get it wrong, like wchar_t
and std::wstring
. It takes discipline and some experience to "get it right".
Not all compilers are created equal. You cannot use all the latest C++ language features, or use libraries that rely on those features, if you require your source to compile on other C++ compilers. Check the compatibility chart first.
Another thing is endianess. Just one example, when you're writing a stream of integers to file on one platform (say, x86 or x86_64), and then read it back again on a different platform (say, POWER), you can run into problems. Why would you write integers to file? Well, UTF-16 is integers... again, discipline and some experience go a long way toward making this rather painless.
Once you've checked all those boxes, you need to make sure of the availability of the libraries you base your code on. While std::
is safe (but see "not all compilers are created equal" above), something as innocent as boost::
can become a problem if you're looking beyond the mainstream. (I helped the Boost guys to fix one or two showstoppers regarding AIX / Visual Age in past years simply because they didn't have access to that platform for testing new releases...)
Oh, and watch out for the various licensing schemes out there. Some frameworks that improve your cross-platform capabilities -- like Qt or Cygwin -- have their strings attached. That is not to say they are not a big help in the right circumstances, just that you need to be aware of copyleft / proprietary licensing requirements.
All that being said, there is Wine ("Wine is not emulation"), which makes executables compiled for Windows run on a variety of Unix-alike systems (Linux, OS X, *BSD, Solaris). There are certain limits to its capabilities, but it's getting better all the time.

- 67,862
- 21
- 134
- 209
-
4The Java mantra actually works out as "Compile once, debug everywhere with an appropriate VM." – Deduplicator Oct 20 '15 at 20:59
-
-
"GTK+" - well, of course, with C++ you should use the official `gtkmm` bindings, rather than reinventing this wheel. Plus, `gtkmm` makes a lot more effort to use standard C++ features wherever possible, which adds up to a much better coding (and in my case, learning) experience IMO. – underscore_d Apr 15 '16 at 12:21
Yes. No. Maybe. What is cross-platform C++ code? Cross-platform C++ code is such a code that can be compiled under different operation systems without the need to be modified.
That means, if you explicitly use any platform-dependant headers, your code is no longer cross-platform. Qt solves this problem in the following way: they provide wrappers for everything that is platform-specific. For example, imagine that you are using QFile
to open/read/write a file. Your code looks like
QFile file(filename);
file.open(QFile::ReadOnly);
//other stuff
You can compile this code under any OS as long as you have a suitable compiler and Qt libraries for that OS. The code hidden under QFile
will use the OS-appropriate file-handling functions, but that shouldn't concern you.
Also, if you only use the standard library, your code can be compiled anywhere where a C++ compiler is present.
The already-compiled applications, however, are not cross-platform in a way that, say, Java applications are - for instance, you can't compile an app for Windows and then run in in Linux, you will have to recompile your code under Linux instead.

- 29,228
- 8
- 68
- 105
-
-
You should rather say it the other way around -- Linux executables not running on Windows -- since [Wine](https://www.winehq.org/) is doing some pretty amazing things these days. ;-) – DevSolar Oct 21 '15 at 07:07
-
"You will have to recompile tour code under Linux instead" - There's Wine, and WSL if you want to do the opposite. – Thor Lancaster Jul 20 '23 at 15:58
C++ is cross-platform. You can use it to build applications that will run on many different operating systems.
What is not cross-platform is the compilers that translate C++ into object code. No single compiler, to my knowledge, has all the necessary features so that when you use it to compile a C++ program, it will automatically run on Windows, Linux and Mac OS.
Qt Creator is integrated with multiple compilers and has build automation. It makes it easy to switch between different setups and target platforms. It provides support for building, running and deploying C++ applications not only for desktop environments but also for mobile devices.

- 1,135
- 1
- 8
- 13
-
1No single C or C++ compiler has ever **aspired** to create cross-platform binaries, because it is simply not possible. Binaries do only work in one specific environment. Java, for example, only works in a Java VM. ;-) – DevSolar Oct 20 '15 at 14:49
-
@DevSolar: To be honest, there was a period when you had the Windows 9X and Windows NT platforms, and you could (with a bit of effort) create cross-platform binaries for the two. – MSalters Oct 20 '15 at 22:45
-
1Apple used to have "universal binaries" that would run on both Intel and PowerPC architecture, too, when they made the switch to Intel processors. Later they also added capability to support both 32-bit and 64-bit versions of either processor, so you could have a single binary that would run on four different processors. – Crowman Oct 20 '15 at 23:50
-
As with everything else in this thread, it depends what you mean by the term, in this case 'binaries'. All variants currently advertising themselves as cross-platform are really just archives containing different images for different platforms. Is that cross-platform? By a trivial definition, sure, but it's only minorly different from distributing a zip with 4 separate binaries. – underscore_d Apr 15 '16 at 12:24
C++ is a programming language. Text. As such, it doesn't run anywhere.
Conforming Standard C++ code is expected to behave equally on any platform; "cross-platform" if you want. Writing (strictly) conforming C++ code requires pedantry because some assumptions often made have dependencies on details that are final to the actual implementation and this is inherited from the targets C++ itself aims to.
Notice we're still talking about C++ code, not C++ programs. Indeed, when we pass to term "program", we've no more guarantees because we aren't talking about C++ anymore; rather, the output of the compiler. This is where portability begins to fade away: executable format, ISA, ABI, low-level routines and so on.
Can you rely on that? If you can't, then you need to integrate your C++ program in the environment it will run on, by recompiling it or using platform-specific elements.

- 8,220
- 2
- 26
- 45