Does using -std=c++11 break binary compatibility? - c++

I've looked hard for this question - it seems an obvious one to ask - but I haven't found it: Is a module compiled with "-std=c++11" (g++) binary compatible with modules that are not compiled with the option? (That is, can I link them together safely?) Both compilations would use the exact same version of g++.
To be more precise, using gcc 4.9.0, can I only use the "-std=c++11" on specific compilation units and then let the others compile without the option.

An authoritative reference can be found in gcc's C++11 ABI Compatibility page.
The short summary is: the are no language reasons the ABI gets broken but there are a number of mandated changes which cause the standard C++ library shipping with gcc to change.

Related

GCC ABI compatibility between versions 10 and 11 [duplicate]

As far as I've understood, it is not possible to link libraries that use different versions of GCC's Application Binary Interface (ABI). Are there ABI changes to every version of GCC? Is it possible to link a library built with 4.3.1 if I use, say, GCC 4.3.2? Is there a matrix of some sort that lists all the ways I can combine GCC versions?
Since gcc-3.4.0, the ABI is forward compatible. I.E. a library made using an older release can be linked with a newer one and it should work (the reverse doesn't). Obviously, there could be bugs, but there is only one mentionned in the documentation: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33678
The official ABI page points to an ABIcheck. This tool may do, what you want.
Ugh, yikes.
How can you tell which gcc compiled a given binary? Here is the
death notice from gcc-4.7.2-1-mingw32.README.txt :
Binary incompatibility notice!
The C and C++ ABI changed in GCC 4.7.0, which means in general you can't
link together binaries compiled with this version of the compiler and
with versions before GCC 4.7.0. In particular:
The option -mms-bitfields is enabled by default, which means the bitfield layout
follows the convention of the Microsoft compiler.
C++ class-member functions now follow the __thiscall calling convention.
The compiler now assumes that the caller pops the stack for the
implicit arguments pointing to an aggregate return value. This affects
functions returning structs by value, like the complex math type.

Can I link an object compiled with clang c++11 with another compiled with c++17

I'm looking specifically for a clang answer to this question. If I compile one object with -std=c++11 and another with -std=c++17 can they be safely linked?
The answer posted here by Jonathan Wakely is correct for Clang as well.
Easy answer: if you're compiling both of the objects yourself, the -std option you choose won't affect the final outcome.
Most of a given C++ ABI is decided by the standard library. The rest is assorted runtime support such as exceptions, compiler builtins (which may actually dispatch to the standard library), and things like that. libstdc++ ABI compatibility is an explicit goal of for Clang, so you're ok here.
If you're using the same compiler version, the -std option will change which symbols get exposed to code when you compile. However, libstdc++'s ABI for stable features is forwards compatible, so you'd also be OK here too.
Harder answer: Your comments suggest you have the source, but if you only have object files and are just doing the final link, there's a good chance it will work unless the version of Clang used to build the std=c++11 object is very old. The g++ and libstdc++ authors went out of their way to version symbols, so the chances of you having something that links, but then fails in a hard to diagnose way is basically zero. (This is referred to in the second to last paragraph in Jonathan's answer).
Again, since Clang aims to keep compatibility with libstdc++'s ABI, you should be fine. There are other details, but the vast majority are addressed in Jonathan's answer, and he's in a better position to explain it than I am.

If clang++ and g++ are ABI incompatible, what is used for shared libraries in binary?

clang++ and g++ are ABI incompatible, even for things as core as standard containers, according to, e.g., the clang++ website.
Debian ships with C++ shared libraries, i.e. libboost, etc... that are compiled with ~something and user programs using both compiler generally work, and the library names aren't mangled with the compiler that was used for them. When you install clang, debian doesn't go and pull in duplicate versions of every C++ library installed on your system.
What's the deal? Is the ability of clang to link against distro-provided C++ libraries just way stronger than the (thankfully cautious) compiler devs describe it to be?
even for things as core as standard containers
Standard containers are not all that "core". (For typical implementations) they are implemented entirely in valid C++ in headers, and if you compile the same headers with G++ and Clang++ you'll get ABI compatible output. You should only get incompatibilities "even for things as core as standard containers" if you use different versions of the container headers, not just by using Clang instead of GCC.
Both GCC and Clang conform to a cross-vendor, cross-platform C++ ABI (originally developed for the Itanium architecture, but also used for x86, x86_64, SPARC etc.) The really core things such as class layout, name mangling, exception handling, vtables etc. are specified by that ABI and Clang and GCC both follow it.
So in other words, if you compile the same source with GCC and Clang you'll get ABI-compatible binaries.
If you want to understand this stuff better see my What's an ABI and why is it so complicated? slides.
G++ and Clang are for the vast majority completely ABI compatible. Furthermore, ABI incompatibilities for Standard containers are properties of the standard library implementation (libstdc++ or libc++), not the compiler. Therefore, there is no need for any re-compilation.
Clang could never have gotten off the ground if it was not ABI compatible with g++, as it would be basically unusable without a pre-existing large following. In fact, Clang is so compatible with GCC, they ape virtually all of g++'s command-line interface, compiler intrinsics, bugs, etc, so that you can literally just drop in Clang instead of G++ and the vast majority of the time, everything will just work.
This probably will not answer the exact question correctly:
Some time ago I tried to compile some object files wih gcc, another object files with clang. Finally I linked everything together and it worked correctly.
I believe Linux distributions uses gcc, because I examined some Makefile's of Ubuntu and CentOS and they used gcc.

Are g++ and clang++ 100% binary compatible? [duplicate]

If I build a static library with llvm-gcc, then link it with a program compiled using mingw gcc, will the result work?
The same for other combinations of llvm-gcc, clang and normal gcc. I'm interested in how this works out on Linux (using normal non-mingw gcc, of course) and other platforms as well, but the emphasis is on Windows.
I'm also interested in all languages, but with a strong emphasis on C and C++ - obviously clang doesn't support Fortran etc, but I believe llvm-gcc does.
I assume they all use the ELF file format, but what about call conventions, virtual table layouts etc?
Yes, for C code Clang and GCC are compatible (they both use the GNU Toolchain for linking, in fact.) You just have to make sure that you tell clang to create compiled objects and not intermediate bitcode objects. C ABI is well-defined, so the only issue is storage format.
C++ is not portable between compilers in the slightest; different compilers use different virtual table calls, constructors, destruction, name mangling, template implementations, etc. As a rule you should assume objects from one C++ compiler will not work with another.
However yes, at the time of writing Clang++ is able to use GCC/C++ compiled libraries as well; I recently set up a rig to compile C++ programs with clang using G++'s standard runtime library and it compiles+links just fine.
I don't know the answer, but slide 10 in this presentation seems to imply that the ".o" files produced by llvmgcc contain LLVM bytecode (.bc) instead of the usual target-specific object code, so that link-time optimization is possible. However, the LLVM linker should be able to link LLVM code with code produced by "normal" GCC, as the next slide says "link in native .o files and libraries here".
LLVM is a Linux tool, I have sometimes found that Linux compilers don't work quite right on Windows. I would be curious whether you get it to work or not.
I use -m i386pep when linking clang's .o files by ld. llvm's devotion to integrating with gcc is seen openly at http://dragonegg.llvm.org/ so its very intuitive to guess llvm family will greatly be cross-compatible with gcc tool-chain.
Sorry - I was coming back to llvm after a break, and have never done much more than the tutorial. First time around, I kind of burned out after the struggle getting LLVM 2.6 to build on MinGW GCC - thankfully not a problem with LLVM 2.7.
Going through the tutorial again today I noticed in Chapter 5 of the tutorial not only a clear statement that LLVM uses the ABI (Application Binary Interface) of the platform, but also that the tutorial compiler depends on this to allow access to external functions such as sin and cos.
I still don't know whether the compatible ABI extends to C++, though. That's not an issue of call conventions so much as name mangling, struct layout and vtable layout.
Being able to make C function calls is enough for most things, there's still a few issues where I care about C++.
Hopefully they fixed it but I avoid llvm-gcc because I (also) use llvm as a cross compiler and when you use llvm-gcc -m32 on a 64 bit machine the -m32 is ignored and you get 64 bit ints which have to be faked on your 32 bit target machine. Clang does not have that bug nor does gcc. Also the more I use clang the more I like. As to your direct question, dont know, in theory these days targets have well known or used calling conventions. And you would hope both gcc and llvm conform to the same but you never know. the simplest way to find this out is to write a couple of simple functions, compile and disassemble using both tool sets and see how they pass operands to the functions.

How to properly switch between gcc versions?

I want to play with C++ 2011, so I need the unreleased gcc 4.7. I was able to succesfully get the svn trunk and compile it.
I want to keep the default gcc of my system for safety, so I configured gcc4.7 with a --prefix and installed it in a non-standard location.
Now how should I enable gcc 4.7 over the default gcc of my system ?
I already changed the CC and CXX variables, I updated my PATH to point on the gcc 4.7 bin dir first. When I type gcc --version I get 4.7 OK.
But gcc is more than just an executable. There are many executables in gcc install dir. There are also default includes and std lib c++.
So far, every blog entry / SO question I found on this subject speaks only about the gcc and g++ executables.
Can anyone give me a list of the changes I need to do to the environment to fully use gcc 4.7 ?
update LD_LIBRARY_PATH ? How to give precedence to gcc 4.7 system includes ? Are there other things to consider ?
Thanks in advance.
I would think that THE g++ is pretty much tangled up with things using C++ as the C library is tangled up with the system! Any layout changes in the C++ library classes will cause incompatibilities with other C++ programs or libraries. Thus, I wouldn't replace the system's C++ compiler or, more importantly, its standard C++ library at all (unless, maybe, the compiler vendor makes a strong claim that they retained binary compatibility with the version you are replacing).
To play or even use a different version of g++, using the prefix approach works fine. All the compiler specific tools are implicitly called from within g++ using an appropriate version and tools like ar, ld, ranblib, etc. are not really depending on the compiler version anyway. The important components uses internally are the standard library (both the headers and the library) and the preprocessor. When calling a version of g++ it figures out which of these it really needs.
BTW, when you want to play with C++2011 you can also have a look at clang.
The simplest answer is: nothing; it just works. :)
GCC finds what it needs first relative to itself, second in the "prefix" it was configured with, and finally in the standard places. By this means it's perfectly safe to relocate it wherever you like, as long as you relocate all of it - but beware that the fall back behaviour can hide brokenness if the install is incomplete.
Look at the GCC Configuration docs. I am using program suffixes to distinguish between the different GCC versions. To do that add, e.g., --progam-suffix=-4.7 to your ./configure invocation.