15

I understand that C++ compilers are not compatible with each other. However, I was unable to find anything on this topic for C in particular. I know that the C standard leaves a lot of room for compilers to implement things however they see fit: for example, the size and alignment of most (all?) data types is implementation-defined save for some minimal guarantees. Therefore, two compilers (or two versions of the same compiler) can disagree on numerous details.

Am I correct in thinking that there's no guarantee that two object files compiled with different compilers will actually link properly? For example, the size of pointers could be 32 bits in one object file and 64 bits in the other. But if that's so, why are C libraries sometimes distributed in precompiled form? Is there an expectation that I'll use the same compiler they did (e.g. gcc), or some de facto standard being used to ensure binary compatibility? And how do other languages with a Foreign Language Interface ensure things will line up properly when linking with C object files?

6
  • As far as I can remember, C object files should be compatible with each other as long as they are compiled for the same platform. An object file is just an archive containing loadable binary code with some symbol table that can be used to access each symbol inside the module.
    – Giorgio
    Commented Apr 11, 2014 at 18:36
  • 2
    libs can be made compatible, I don't think obj are guaranteed to be Commented Apr 11, 2014 at 19:10
  • @Giorgo By "same platform", do you mean CPU architecture or CPU architecture + OS?
    – Doval
    Commented Apr 11, 2014 at 19:12
  • 1
    @ratchetfreak I was under the impression a lib is for the most part just a concatenation of multiple object files. Is that wrong?
    – Doval
    Commented Apr 11, 2014 at 19:12
  • I would not expect objects to be compatible across different compilers.
    – old_timer
    Commented Apr 12, 2014 at 2:55

2 Answers 2

10

The general answer is no, C language compilers are not compatible with each other. The C language standard does not define any kind of binary interoperability, and most compiler writers don't even try.

I need to qualify that. The objects emitted by a C compiler have to be linked with runtime libraries to produce either an executable or a runtime linkable library. Although the visible functions provided by the C runtime library should be compatible, there will also be non-visible functions that are unique to the implementation and prevent interoperability.

This lack of compatibility also extends to different versions of the same compiler. In general, programs and libraries compiled with older and newer versions of a compiler cannot be linked together, and those compiled with MSVC cannot be linked with those compiled by GCC.

There is a specific and very useful exception. Every platform provides a dynamic linking ABI (Application Binary Interface) and any program in any language that can conform to that ABI is compatible. Therefore it is generally possible to build a DLL (on Windows) with MSVC (or something else) and call it from a program compiled by a different version of MSVC or by GCC and vice versa.

There are two other ABIs on Windows: COM and .NET assemblies, and they span a wide range of languages. So interoperability is definitely possible, but compatible they are not.


The degree of incompatibility can easily be seen by comparing the linker maps. For GNU use ld -M, for MSVC use link /map. Study the two generated files. Both will have names in them that you recognise, such as printf and main, although (depending on options) the names are likely to be mangled in various ways. They will also have names that are completely different, many of which you won't recognise. In order for object files produced by different compilers to be compatible they have to agree on all those names, and they never do. Not even different versions of the same compiler can always do that.

6
  • 1
    This answer seems to contradict Bart's; it sounds like only shared libraries are compatible. Could you explain why the non-visible, implementation-specific functions of the C runtime library prevent interoperability? You also say "the objects emitted by a C compiler have to be linked with runtime libraries to produce either an executable or a runtime linkable library" - what about static libraries?
    – Doval
    Commented Apr 14, 2014 at 12:22
  • As Bart said, only libraries with an ABI are compatible. Shared libraries (on Unix) are one kind of ABI, there are others. Write HelloWorld.c, compile it with MSVC and gcc, compare the maps and you'll see how different they are. 'Runtime libraries' means the essential support functions automatically referenced in every C/C++ compile, which may be statically or dynamically linked. Read the map or the CRT source code to see them.
    – david.pfx
    Commented Apr 14, 2014 at 14:21
  • I don't know what comparing the maps means so I'll be a little bit more specific: is it safe to assume in practice that all compilers for a given CPU architecture AND OS combination are compatible? E.g. I have main.c, which I compile with gcc and mylibrary.c which I compile with clang, both targeting Linux x64. Assuming a reasonably mainstream OS (Linux, Mac, Windows), is it safe to assume that would work regardless of what the two compilers are?
    – Doval
    Commented Apr 14, 2014 at 17:17
  • 1
    Highly unlikely, check the clang link map. See edit.
    – david.pfx
    Commented Apr 15, 2014 at 0:55
  • "Every platform provides a dynamic linking ABI..." Can you please explain what you mean by 'dynamic linking ABI', if possible citing a reference.
    – Declan
    Commented Mar 21, 2021 at 18:25
20

What you are looking for in called an ABI (Application Binary Interface).

The C language does not define an ABI, so in that sense there is indeed no guarantee that C files compiled with different compilers will work with each other.

On the other hand, on most platforms the OS defines an ABI for interfacing with it and all compilers targeting that OS & processor family also use that same ABI for interfacing with non-OS components. So, in practice, C objects created by different compilers can work with each other.

2
  • That makes sense. I take it shared libraries follow the OS's ABI too?
    – Doval
    Commented Apr 11, 2014 at 22:26
  • 3
    @Doval Especially shared libraries, they need to be callable by the outside world. Commented Apr 11, 2014 at 22:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.