Standard libraries of LLVM C++ and GNU C++ have different headers - c++

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.

Related

Interoperability between Boost and C++11

What is the extent of interoperability between C++11 and a recent version of Boost (say 1.55) built with a C++11 compiler.
Does the behavior of any library feature change depending on whether I built the libraries with c++11 flags enabled or not?
How do language features like lambda functions cooperate with Boost's lambdas?
You cannot use objects built with gcc with and without -std=c++11 together. You will get link errors or even runtime crashes. I cannot vouch for other C++ implementations. So at least with gcc, you do need to build a separate version of Boost with c++11 mode enabled.
They are pretty much independent. They don't cooperate and don't interfere with each other.
EDIT I see people are still reading (and upvoting!) this answer. Point 1 is no longer true (or perhaps never was true). Versions of gcc from I think 5.1 upwards use an ABI compatible with -std=<anything> by default.
No behaviours change: at the code level Boost is compatible with both C++03 and C++11.
However, at the object level you won't be able to mix and match: if your program is compiled as C++11, and you're using some non-header Boost libraries, you will have to build those Boost libraries as C++11 as well. This is because the respective C++ runtimes of your toolchain for each version of the language cannot be guaranteed to have ABI compatibility.

C++ standard library implementations in different compilers

I was wondering which C++ standard libraries are in use in different C++ compilers. I tried searching for it, but couldn't find a comprehensive list.
I know Dinkumware's implementation is used by msvc and icc, libstdc++ is used by gcc, and libc++ is used in clang. But what about Digital Mars C++, or Embarcadero's bcc, or IBM's xlC++?
A shortlist:
GCC: uses its own libstdc++.
MSVC: uses its own msvcrp, which is bought from Dinkumware, then dismembered to work around MSVC's bad C++ language support (so it's not really Dinkumware anymore).
Clang: uses LLVM's libc++ if passed the -stdlib=libc++ option. It can also use GCC's libstdc++ and in also MSVC's library (it generates binary compatible code in all cases).
ICC: uses GCC libstdc++ on Linux and MSVC's library on Windows. It also tries to mimick both compilers on these platforms.
Note there are other compilers and (independent) C++ standard library implementations I have not covered here.

g++ always backward-compatible with "older" static libraries?

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.

GCC 4.7/4.8 as Xcode's C/C++ Compiler

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++.

clang++, boost::spirit and c++11

I'm using clang++ (clang-421.0.60), packaged with Xcode 4.6, and came across an issue with boost::spirit. If I compile without any flags, everything compile fine. If I compile with '-std=c++11', then I get the following error (on including of "boost/spirit/include/qi.hpp"):
In file included from test_spirit11.cpp:1:
In file included from /usr/local/include/boost/spirit/include/qi.hpp:16:
In file included from /usr/local/include/boost/spirit/home/qi.hpp:14:
In file included from /usr/local/include/boost/spirit/home/qi/action.hpp:14:
In file included from /usr/local/include/boost/spirit/home/qi/action/action.hpp:21:
/usr/local/include/boost/spirit/home/support/action_dispatch.hpp:21:10: fatal error:
'type_traits' file not found
#include <type_traits>
The problem is that the default library used (stdlibc++) has type_traits defined as 'tr1/type_traits', whereas boost::spirit expects just 'type_traits'. I can of course fix this problem by doing:
clang++ -std=c++11 -stdlib=libc++ <...>
While I would love to use libc++, the practicality of doing so is difficult (many libraries still use and depend on stdlibc++). Thus, I am forced to not use libc++.
Does anyone have any suggestions on how to deal with this? I really wish that either more library maintainers support libc++ or that Apple provided a newer version of stdlibc++. It's been a major frustration to have access to new c++11 features, but not be able to fully use them due to lack of library support.
The problem is that the default library used (stdlibc++)
It's called libstdc++
has type_traits defined as 'tr1/type_traits', whereas boost::spirit expects just 'type_traits'.
<tr1/type_traits> is not the same thing, it's a different header entirely. boost::spirit wants the C++11 header <type_traits> which is a different header (though they do contain some similar functionality, in different namespaces.)
The problem is probably that you're using the libstdc++ that comes with Apple's ancient version of GCC (4.2) which doesn't support C++11.
If you want to use C++11 you either need to use clang with libc++ or install a newer GCC to get a newer libstdc++. Apple won't provide a newer GCC for licensing reasons, but you can install it yourself and tell Xcode how to find the headers and libs.
If you don't want to use C++11 features in boost you can disable it.
Edit boost clang.hpp to manage features.
For example to disable type_traits file not found error you can add to the end:
#define BOOST_NO_VARIADIC_TEMPLATES