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

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

Related

Build Fails Using GCC-11 Due to Some Missing Standard Library Headers

After upgrading to gcc-11, which is shipped with Ubuntu 22.04, I started to get new compiler errors due to some missing Standard Library header files. Whereas previous gcc versions don't.
When I started to look into it, I learned from Porting to GCC 11 page, under the "Header dependency changes" section, that this is a new behavior due to some new specs in the standard itself.
Now, my question is: does the implementation of a particular C++ standard (i.e. C++17) change from one gcc version to another (i.e. gcc-9 and gcc-11)? I mean, how can the build fail if I'm building with different gcc versions but against the same C++ standard version (i.e. -std=c++17)?
And is that C++ Standard Library new requirement - of not to include other headers that were being used internally by the library - part of C++17 or C++20?
To get over this...
I manually included those header files where they were missing, and the build just succeeded.
However, I was expecting behavior to be consistent when I build against a certain C++ version with different gcc versions. Or, am I missing something?
Thanks to JaMiT note, I realized that I got the note from GCC wrong.
It's only their implementation of the Standard that got changed in GCC 11, and not the Standard itself.
When you thoroughly read the referenced section from that article, you can see that.
Header dependency changes
Some C++ Standard Library headers have been changed to no longer
include other headers that were being used internally by the library.
As such, C++ programs that used standard library components without
including the right headers will no longer compile.
The following headers are used less widely in libstdc++ and may need
to be included explicitly when compiled with GCC 11:
<limits> (for std::numeric_limits)
<memory> (for std::unique_ptr, std::shared_ptr etc.)
<utility> (for std::pair, std::tuple_size, std::index_sequence etc.)
<thread> (for members of namespace std::this_thread.)

MinGW standard library missing any.h?

I recently downloaded mingw from http://www.mingw.org/ and installed its c++ compiler and dependencies, which include installing standard library headers. I have also successfully compiled a hello world program, compilation is fine, and common old headers are there and work fine (such as string.h).
However, when I attempted to #include <any>, it threw an error that any.h does not exist. And sure enough, when I look in mingw\include\, there is no any.h (and I see other things missing, such as variant.h).
I've looked through the mingw package manager, and I have the standard library stuff installed, and there's nothing else relevant to install. Does minGW support C++17? If so, how can I get these newer header files? It seems like this should be something really obvious.
You need mingw-w64, which provides more recent GCC versions:
http://mingw-w64.org
You can find a 7.2.0 download here:
http://mingw-w64.org/doku.php/download/mingw-builds
The any feature requires C++17 support, so if your compiler implementation actually does support it, you probably want to specify it on the command line like this:
g++ -std=c++17 a.cpp
Of course, this requires a modern C++ compiler, like that you can get from nuwen.net.

Standard libraries of LLVM C++ and GNU C++ have different 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.

Stop Apple clang from adding Xcode paths to standard include paths

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.

Including C++ 11 headers with Clang / LLVM

I have installed clang and llvm from source, and am trying to compile some C++ code using features of the new standard.
I have found that while for example the use of for ranges e.g. for (i : vector) works fine, I am having trouble (cannot find header file) when I need to import a header e.g. <unordered_set> or <tuple>.
Do I need to use the new libc++ to use these headers, or is there just a simple build change I need to make? At the moment I have just built clang and llvm into a folder in my home directory, and am calling clang++ from there.
See http://clang.llvm.org/get_started.html.
If you intend to work on Clang C++ support, you may need to tell it how to find your C++ standard library headers. If Clang cannot find your system libstdc++ headers, please follow these instructions:
gcc -v -x c++ /dev/null -fsyntax-only to get the path.
Look for the comment "FIXME: temporary hack: hard-coded paths" in clang/lib/Frontend/InitHeaderSearch.cpp and change the lines below to include that path.
While the standard library comes with distributions of your compiler, when you're building it yourself, you still need to build the standard library itself. Some of its components may be header-only, but not all of them are.
So you do need to at least download the library, if not build it. Clang can use GCC's libstdc++, but they also have their libc++ project.