C++ Compiler Compatibility

Started by
7 comments, last by SiCrane 16 years, 3 months ago
It seems to me that if a compiler is written and conforms to the C++ standard, then anything compiled by that compiler should be compatible with other compilers that conform to the standard. This doesn't seem to be the case because there are usually multiple development library options, one for GCC, one for VC++ etc. There are a lot of C++ compilers out there. Are they really all different enough that a library compiled with one of them can not be linked to using a different compiler? How does this work? Is it the same for other languages?
Advertisement
Implementation details can differ. Even if the standard libraries from 2 different compilers produce the exact same effect to a user, they can do things differently in the implementation. There's always more than 1 way to achieve the same result.

And even if there was a standard implementation, optimisation differences between compilers would also make them incompatible.

Besides, the implementations of static libraries themselves are different. VC++ uses .lib, while GCC uses something else (I can't remember right now).
NextWar: The Quest for Earth available now for Windows Phone 7.
Quote:Original post by Sc4Freak
Besides, the implementations of static libraries themselves are different. VC++ uses .lib, while GCC uses something else (I can't remember right now).


That's platform dependent, not compiler dependent. If you use GCC on windows, it will generate .lib as well. You're thinking of .a which is the linux library format.

Any library built with GCC will work with any other IDE/Compiler on the same platform.

There are a couple minor things: like GCC wants you to have an empty line at the end of every file, whereas VC++ doesn't care as much about that. Both compilers generate the same warning, I believe VC++ just has it at a lesser warning level. But otherwise, you're safe building a library in any (relatively) standards compliant compiler/linker.

-me
I think Antheus gave me a better understanding of the actual question. [EDIT: heh, Antheus's post disappeared. I basically just restated exactly what he said in different words anyway [smile]]

Different hardware and operating systems have different conventions for what the output of C++ linkers should look like. So a library built for Linux will typically not work on Windows or Mac or mobile phone, or whatever else.

Like I said, however, any C or C++ library built on windows in one IDE will definitely work on windows in another IDE.

Different languages work differently: For example, Java runs in a Virtual Machine so an executable in java can be exactly the same on every platform (you just need separate virtual machines written for each platform to execute that code).

-me
The main differences are architecture, standard naming schemes and calling conventions and object layout. These all fall under the umbrella term ABI, or Application Binary Interface.

Obviously, object files between different processor architectures will not be interoperable. Even different operating systems could be problematic (I imagine, I've never worked at that level).

Unlike C, in which each external object must have a unique name, C++ allows mutliple objects conceptually share a name by name mangling. For example, C++ allows function overloading, where the same function name can take different types of arguments. Most C++ compilers will produce names in the object files that indicate what arguments each function takes, something like this (simplified of course):

void foo( Bar bar ); // mangled to __foo__Barvoid foo( std::string ); // mangled to __foo__std__string


One might think it would make sense for each compiler to standardise the naming conventions, however the opposite is done. They intentionally choose different schemes because there is no standard for object layout.

The C++ standard does not go into detail about how polymorphism is implemented. While in practise most compilers choose the vtable layout. This is often implemented by placing a pointer to the vtable at the "start" of the object (in memory). The vtable is some kind of array of function pointers. With multiple inheritance, this is even trickier. Each object could have multiple vtables. What about the entries in the vtable? The order of functions in the vtable is also arbitrary (for example, a compiler could choose to always have the first entry the virtual destructor, where applicable).

Additionally we have different calling conventions. Attempting to call a function with the wrong convention will fail.

Type sizes can vary. sizeof() everything except char isn't defined (although there are minimum limits set by the C standard, which the C++ standard includes... sortof).

These are just a number of potential problems, off the top of my head.
Quote:Like I said, however, any C or C++ library built on windows in one IDE will definitely work on windows in another IDE.


It sounds like what rip-off is saying is that this isn't true, correct?
Quote:Original post by Uphoreum
It sounds like what rip-off is saying is that this isn't true, correct?

Correct. As an example, Borland compilers produce libraries which follow the OMF (Intel Object Module Format) standard. Microsoft compilers on the other hand produce libraries in COFF (Common Object File Format). Trying to link an OMF library in Visual C++ 2008 results in the error: fatal error LNK 1136: invalid or corrupt file. Equally, trying to link a COFF library under Borland results in: Error: 'NAME.LIB' contains invalid OMF record, type 0x21 (possibly COFF)

Σnigma
I'd like to point out that even if the library formats were exactly the same, and from the same compiler, they still aren't guaranteed to be compatible.

For example, code utilising the STL from VS2003 is not compatible by default with VS2005. There are various reasons, one of them being that Microsoft implemented checked iterators in VS2005's version of the STL, and so generated different code to VS2003. It's still standards compliant, but won't work between the two compilers.

If, for example, you disable checked iterators in VS2005, it means that any other library that uses the STL that doesn't disable checked iterators will not work, even if it too came from VS2005. World of pain.
NextWar: The Quest for Earth available now for Windows Phone 7.
On some platforms there may be minimal levels of de facto binary compatibility. For instance, on Windows machines, there's the COM standard, which dictates binary layouts for sharing objects across binaries. Most C++ compilers on Windows allow the implementation of COM objects with C++ classes. This means that, for example, an executable compiled with one compiler can use a DLL compiled in another compiler if the exposed interface is limited to abstract base classes with functions that only use types that are valid COM types (basically abstract base classes, primitives and null-terminated strings), even if the classes don't actually implement any COM interfaces.

This topic is closed to new replies.

Advertisement