clang, g++, icc link compatibity?

(Sorry if this is documented somewhere, but I couldn’t find it.)

Does anyone know what limitations currently exist when linking together C++ object produced by clang with those produced by c++ and/or Intel’s icc?

My impression back in the day was that incompatible ABI’s made it unsafe to link together C++ object code from different compiler vendors/versions. Not just with name mangling, but also with exceptions and perhaps other issues. I’m not only asking about linking to C++ standard libraries, but also situations like:

clang++ -c foo.cpp
g++ -c bar.cpp
clang++ a.o b.o

Experimentally it seems to work okay, but I wasn’t sure if that tells the whole story.

(Sorry if this is documented somewhere, but I couldn't find it.)

Does anyone know what limitations currently exist when linking together
C++ object produced by clang with those produced by c++ and/or Intel's icc?

My impression back in the day was that incompatible ABI's made it unsafe
to link together C++ object code from different compiler vendors/versions.
Not just with name mangling, but also with exceptions and perhaps other
issues. I'm not only asking about linking to C++ standard libraries, but
also situations like:

clang++ -c foo.cpp
g++ -c bar.cpp
clang++ a.o b.o

Experimentally it seems to work okay, but I wasn't sure if that tells the
whole story.

All these compilers attempt to implement the Itanium ABI. There's a common
working group that attempts to keep this ABI evolving as new language
features are added that have ABI surface area so that this continues to be
true.

(basically: yes, this is meant to work. When it doesn't it's likely a bug
in one of the compilers and/or the Itanium ABI spec)

Thanks David. So it sounds like you’re saying that all the previously messy stuff like vtable layouts, exception handling, etc. are non-issues for current versions of those three compilers. Is that right?

David's reply is very very misleading -

You're not only dealing with potential incompatibilities at the ABI
level. There is also the STL that can play a role.

Is clang using the system STL or libc++? (I think libc++ does play
nice with GNU STL in some circumstances, but not all afaik)

If all 3 compilers are on the same page with the ABI, using the same
EH, the same STL and same runtime - yes in theory, barring things I
can't think right now - it should work.

So double check which runtime/STL ICC is relying on.

> Thanks David. So it sounds like you're saying that all the previously
messy
> stuff like vtable layouts, exception handling, etc. are non-issues for
> current versions of those three compilers. Is that right?

David's reply is very very misleading -

You're not only dealing with potential incompatibilities at the ABI
level. There is also the STL that can play a role.

Sure enough, thanks for the clarification.

Is clang using the system STL or libc++? (I think libc++ does play
nice with GNU STL in some circumstances, but not all afaik)

Clang is designed to find the same STL as any locally installed GCC
(obviously if you use some non-default GCC (if you have multiple versions
installed, etc) or force the use of libc++ that'll get more interesting).

If all 3 compilers are on the same page with the ABI, using the same
EH, the same STL and same runtime - yes in theory, barring things I
can't think right now - it should work.

So double check which runtime/STL ICC is relying on.

*nod*

So, modulo any shenanigans about clang and gcc finding different STL headers/libs, and modulo any bugs, as long as they’re using the same Itanium ABI version, I’m probably okay?

So, modulo any shenanigans about clang and gcc finding different STL
headers/libs, and modulo any bugs, as long as they're using the same
Itanium ABI version, I'm probably okay?

Right - basically given the same preprocessed source, any Itanium ABI
conforming compiler should produce compatible object files.

- David

In theory yes, but in practice I would not count on this at all.

Think about it another way - if you have an object compiled with
g++-4.1 would you try to link and include it with other objects built
with clang or gcc-5?

FreeBSD, Linux and Solaris all use the Itanium ABI - Would you try to
take an object compiled on Solaris and link it against some stuff for
Linux. (This is an absurd example, but I hope it really shows my
point)

Bugs are unavoidable and c++ is *hard*

Don't get me wrong - I'm trying to give a conservative answer.

ICC/ICPC uses whatever STL includes and headers are installed on the linux machine. ICC/ICPC is expected to be completely

compatible with the gcc installed on the linux machine as well. It checks for the version of gcc in the user’s path and tailors its

compatibility to that specific version of gcc.

And AFAIK clang/llvm tries to be compatible to the same ABI as well, so the basics should be that all three are expected to be ABI

compatible with each other.

As others have said though, there are lots of possibilities for subtle issues.

Kevin B. Smith

Intel Compiler Architect

> So, modulo any shenanigans about clang and gcc finding different STL
> headers/libs, and modulo any bugs, as long as they're using the same
Itanium
> ABI version, I'm probably okay?

In theory yes, but in practice I would not count on this at all.

Think about it another way - if you have an object compiled with
g++-4.1 would you try to link and include it with other objects built
with clang or gcc-5?

Compatibility with GCC 5 is worth mentioning on its own merits:

libstdc++ from version 5 onwards uses a new abi_tag mechanism, which Clang
does not yet support. Do not expect libstdc++ v5 onwards to work with Clang
for the time being (unless you turn that mechanism off somehow).

This is regrettable: abi_tag is only marginally better than the standard
solution of inline namespaces (you can tag member functions, not just
namespace-scope entities, but otherwise it's essentially the same at the
ABI level), and it means that GCC / libstdc++ is now sort-of deliberately
violating the cross-vendor ABI. But... the GNU project is unlikely to be
interested in making their code work with non-GCC compilers, so this is our
problem to solve.

FreeBSD, Linux and Solaris all use the Itanium ABI - Would you try to

You can enable the old ABI with libstdc++ 5.X, via building your software with -D_GLIBCXX_USE_CXX11_ABI=0. That’ll work fine if you only depend only on libstdc++ itself, because libstdc++ exports symbols for both the old and new ABIs at the same time.

But if your program depends on other C++ libraries that themslves expose c++ std types in their API, and which have been built against the new ABI, then you’re in trouble, because clang cannot compile correctly for the new ABI. So, clang on Fedora 23 should be broken, as they’ve apparently rebuilt all libraries for the new ABI, and I’m sure nobody but libstdc++ bothers to export symbols for both the old and new ABIs.

See
http://developerblog.redhat.com/2015/02/10/gcc-5-in-fedora/

for some more info.