2

Compilers have a lot of freedom in the code they generate. They have complete freedom in the implementation of the VTable, RTTI, exceptions and much more. Even very basic things like the size of a pointer, the way functions are invoked and name mangling can be chosen arbitrarily, independently from operating system and architecture.

Yet, I've never had an issue with compiling a C++ program with any compiler (Clang, GCC, ICC, MSVC), on any operating system (Android, Linux, Mac OS, Windows), on any architecture (x86, x86-64, ARM) and linking it to libraries built with a different compiler.

How are all the binaries files compatible with others?

Do binary files get dynamically "adapted" by the runtime linker or similar?

Did the compilers agree on some standards? If so, where can I find information on these binary-level de-facto standards?

Helloer
  • 417
  • 3
  • 13
  • They are in many times they are not compatible. For example Visual Studio 2015 through 2019 are binary compatible with each other and also clang when compiled in a special mode but these are not compatible with any previous version of Visual Studio or other compilers when compiling c++ code. – drescherjm Dec 11 '20 at 13:19
  • The way your executable interacts with the OS and libraries, depending on processor and OS, is described in the corresponding ABI (https://en.wikipedia.org/wiki/Application_binary_interface). Your (cross-)compiler has to match that to the target system, otherwise you WILL run into issues. – jf_ Dec 11 '20 at 13:43

1 Answers1

1

Often times they are incompatible. Here are some of the incompatibilities that may be found:

Different data type sizes

For example, GCC uses 16 bytes for a long double, while VS aliases it to double (8 bytes). For more information, check this.

This can be easily fixed if both sizes are known, since converting between sizes is trivial (but may result in loss of precision).

Name mangling

This is probably the most known issue. C++ compilers need to decorate symbols so that (among many things) function overloading is possible. There is no standard name mangling scheme, so compilers choose their own, which causes incompatibility, since code compiled with VS, for example, might not recognize the names in a library compiled with GCC, or even an earlier version of VS.

This can be fixed by not decorating the names, and exporting them as C functions, which are undecorated. This, however, means that class methods must be wrapped in C functions in order for them to be exported (because C doesn't understand classes), and this is not really convenient.

Visual C++ name mangling scheme

GCC name mangling scheme

DarkAtom
  • 2,589
  • 1
  • 11
  • 27
  • Interesting! And how about things such as the VTable and exceptions? Those seem extremely common (way more common than `long double`) and complex. Did compilers agree on how to structure the VTable information (API+ABI)? Or did architectures/OSes? Or do those things never work between different compilers? – Helloer Dec 11 '20 at 15:34
  • First of all, no exceptions cross the library boundary, because they are incompatible. As for VTables, did you read the name mangling problem? Classes and all of their functions have decorated names which are already incompatible. Therefore, libraries rarely export classes, so asking about VTables is pretty pointless. – DarkAtom Dec 12 '20 at 16:16