I have a few static libraries, which I'm not the owner of, compiled with an old version of g++ 4.3.2 (c++11/c++0x not activated).
When I compile my code with g++ 4.6 (no c++11) and link it using g++ 4.6 with these
static libraries, it links fine and I do not seem to get any issues at runtime (not tested everything though).
I'm tempted to think that forward compatibility is OK.
Now I'd like to compile my code with gcc 4.8 with c++11 and still link it with those same, not recompiled static libraries.
Are ABI changes in g++ only an issue for linkage forward compatibility or can one get backward compatibility issues too?
The G++ ABI for C++98 code is backward compatible, all the way back to GCC 3.4
So if you compile and link your final executable with GCC 4.8 you can link to objects and libraries built with anything from GCC 3.4 to 4.8 (but no newer)
The C++11 ABI is the same as the C++98 ABI and the standard library types that are common to both C++98 and C++11 have the same definitions, (ignoring GCC 4.7.0 and GCC 4.7.1, which had ABI incompatibilities in std::pair and std::list when using C++11, which have been fixed in 4.7.2 and later versions) so you can link C++98 and C++11 code together (unless the C++11 code was built with GCC 4.7.0 or 4.7.1)
However some C++11 library types are not stable yet and change between releases, e.g. because they were first shipped before the final C++11 standard and had to be changed to match the final rules. So it's not necessarily safe to mix C++11 code built with GCC 4.6 and C++11 code built with GCC 4.8
For your case, where all the C++11 code is built with GCC 4.8 that will be OK. If you upgrade the compiler you should rebuild all the C++11 code with the newer GCC to be safe. (You don't need to rebuild the C++98/C++03 code)
The C++11 standard has as it's goal to maintain backwards compatibility, as does compiler vendors. As long as the library doesn't use anything that "breaks" C++11 standard, the library format itself should be the same.
See this for changes introduced in C++11.
So, presuming the code you are using to call the library (including headers), you should be fine.
Related
We have a library written in C++17. Is there any way we build this library for C++03 ABI (for instance for gcc 4.4 or for modern gcc with std=c++03 on) assuming we fix the headers?
I have to use unordered_map and trie, but not one standard library, nor another one contains both of them.
// works only with LLVM library
#include <unordered_map>
// works only with GNU library
#include <ext/pb_ds/assoc_container.hpp>
I mean which is described on the GCC GNU website.
The program is building in Xcode 7.2.1. I have tried to use GNU C++14, GNU C++11 and C++14, C++11, but it doesn't help.
How this problem may be solved? Probably, my GNU library is too old, can I update it in Xcode? Or, maybe, LLVM has assoc_container.hpp is some other path?
std::unordered_map came in with the C++11 standard, and not all compilers use C++11 (or later) as standard yet meaning you have to add flags when building to be able to use it.
When building with GCC versions prior to 5.1 you should add the flag -std=c++11 (or optionally -std=gnu++11 if you want GCC extensions, or -std=c++0x if you have a really old version of GCC).
An implementation of std::unordered_map is a requirement for C++11. This suggests you are using an older version of stdlibc++.
If you're stuck with that version, Boost provides an implementation that you could use.
You can't expect libc++ (Clang's C++ library) to have GNU extensions. You can, however, mix and match libstc++ and libc++ in the same executable (but not compilation unit) due to the latter's use of inline namespaces, which mean that its symbols won't clash with the former.
Edit:
Seems the OP is compiling on MacOSX using a recent version of clang.
In this case, the libstd++ shipping with the toolchain is a creaking old version without C++11 support. It is deprecated as far as Apple is concerned.
The best bet is to either: modify code to avoid use of extensions in libstdc++ - which in any case appear to C++11 pre-release features
or: build with both libraries (yes, this is totally possible on MacOSX and iOS). Caveat here is that you can only ever use one or the other in any compilation unit.
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.
Apple's clang appears to magically include Xcode header files which conflict with my code. For example, they define stoi() while standard C++ headers do not. Clang does not do this on other platforms, e.g. FreeBSD.
Example of error on Mac OS:
$ clang -I. -I../../../include -c compile.cpp
compile.cpp:949:18: error: call to 'stoi' is ambiguous
arg.iValue = stoi(current.token);
^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/string:4019:37: note:
candidate function
_LIBCPP_FUNC_VIS int stoi (const string& __str, size_t* ...
^
This compile works fine on FreeBSD.
The problem is because in addition to the standard C++ headers in /usr/include/c++, Apple clang is including the headers in the Xcode application tool chain. Is there some way to turn that off without using the -nobuiltininc flag?
The default C++ library for newer versions of clang on OSX is libc++, which is a pretty full implementation of the C++11 standard. The headers are all C++11, and there are no conditional sections to remove methods that should only be available in that standard (e.g. attempting to compile using --std=c++03 doesn't have the desired effect.
The version of stdlib++ that's present in the apple environment doesn't have this issue as (1) it's not a complete implementation of the C++11 standard, and (2) you can actually compile for older c++ standards.
As a result, if you compile using --stdlib=libstdc++, you are compiling against the GNU standard library headers and library which don't have the issue with the definition of std::stoi (and others routines if I'm interpreting the question correctly).
Bear in mind, though, that you have to compile every c++ element of your project with this flag, as otherwise you end up with code that has been compiled with different standard libraries and they will not link together.
The real problem, though, is that if you start using C++11 features and start compiling explicitly with --std=c++11, then you're probably going to encounter this problem at some point in the future with gcc as well. Newer versions of the compiler support more of the C++11 standard, and so would define this routine in the headers and you're back to square one.
I am now currently working on a C++ project, which I wish to use C++11 features with. In this project, I am using the library NTL which is used for number theory stuff.
Due to comfort auto completes Xcode has, I write my code with Xcode and the library NTL is statically linked with flag "-lntl".
Now, I wish to use some C++11 features. Apple's LLVM compiler that is default in Xcode includes such support, but somehow compiling with NTL and iostream doesn't work, unlike with the LLVM GCC 4.2 compiler with Xcode.
And so, I use LLVM GCC 4.2 compiler, but it does not include support for C++11. Therefore, I brew'd gcc48, and I wish now to make Xcode compile its code with gcc4.8.
How can I do that?
--EDIT--
Solved thanks to all comments which advised to change from libc++ to stdlibc++ (GNU libc++) and that solved the problem of NTL not being compiled with Clang.
There are 2 different implementation of C++ run-time library: gcc's libstdc++ and clang's libc++ which are incompatible with each other.
Change the use from libc++ to libstdc++.