Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking for C++11 library features

What is a good way of checking for the presence of specific C++11 features of the standard library.

For compiler features I just went by the way of checking the compiler version for the (IMHO) major compilers (VC++, gcc, clang at the moment, maybe Intel) Although this is not the best and most flexible approach, I don't know of anything better yet, except for clang which has the really nice __has_feature macros.

But it's even worse for library features, which are not coupled that rigidly to the compiler. At the moment I want to use the same approach of checking the compiler version for VC++ (where it's pretty easy, assuming it uses its own library). For clang I can at least use __has_include for large-scale header-based queries. Other than that I guess checking __GLIBCXX__'s value if defined might be a good idea, but then again I cannot find any information of what specific libstdc++ versions introduced which features, other than what the current version supports.

The methods should be kept to preprocessor checks and the like, since I want to use it in a header-only library without any sophisiticated configure procedure and without using any third-party libraries (and yes, boost is third-party).

  1. So what are my possibilities of checking for specific C++11 library features under those (pretty narrow) conditions. Maybe even on the scale of particular functions or types being declared?

  2. If checking for the compiler or library version is still the best approach, where can I find detailed information about the particular C++11 features supported by a specific version of libstdc++ (and maybe other important ones, libc++ perhaps)?

FWIW at the moment I'm interrested in <cstdint>, C++11 <cmath> functions and std::hash, but this may change and is probably not of importance for the general approach.

like image 725
Christian Rau Avatar asked Aug 09 '12 15:08

Christian Rau


2 Answers

There is really nothing nice you can do here besides knowing which compiler in which version implements what and have the proper defines in place.

gcc has a special table for library functionality. The main problem of __has_include are of course additions to the standard that live in old includes. libstdc++ also has the necessary includes, but that doesn't mean the necessary define to enable the content of those files. It also wont tell you anything about the actual amount of available implementation (which sometimes is incomplete).

As you have a header-only library this doesn't apply to you, but is still important: binary incompatibility between C++11 and C++03 can come back and bite you.

I seriously wouldn't approach any of that on my own and rather use Boost.Config. Originally it only described language features but has now expanded to standard library headers.

like image 76
pmr Avatar answered Oct 20 '22 23:10

pmr


You could write autoconf macros to check, and if you do, submit them to http://www.gnu.org/software/autoconf-archive/
The only relevant one so far checks for complete coverage, not for individual features: http://www.gnu.org/software/autoconf-archive/ax_cxx_header_stdcxx_0x.html#ax_cxx_header_stdcxx_0x But that fails the requirement for no complicated configure checks.

Other than that I guess checking __GLIBCXX__'s value if defined might be a good idea,

Looking at the value of __GLIBCXX__ is not useful, it contains the date the version was released which tells you almost nothing about the version (e.g. 4.6.3 is released after 4.7.0 so has a later date in __GLIBCXX__ but has fewer C++11 features.) When using libstdc++ with GCC you want to use the general GCC version numbers in __GLIBC__ and __GLIBC_MINOR__ for checking versions (in general you can only use a given version of libstdc++ with the GCC release it came with.)

Edit: Starting with GCC 7 there is a new macro defined by the libstdc++ headers, _GLIBCXX_RELEASE, which is defined to the same value as GCC's __GNUC__, but is still usable even when using the libstdc++ headers with non-GCC compilers.

but then again I cannot find any information of what specific libstdc++ versions introduced which features, other than what the current version supports.

The libstdc++ C++11 status tables for previous releases are available online where all GCC docs live: http://gcc.gnu.org/onlinedocs/

For 4.7 it's at http://gcc.gnu.org/onlinedocs/gcc-4.7.1/libstdc++/manual/manual/status.html#status.iso.2011 and for 4.6 it's at http://gcc.gnu.org/onlinedocs/gcc-4.6.3/libstdc++/manual/manual/status.html#status.iso.200x and for previous releases is included with the source (but the coverage in pre-4.6 releases is pretty patchy anyway.)

Some added features are listed in the release notes for each version, e.g. http://gcc.gnu.org/gcc-4.7/changes.html (in the libstdc++ section)

Edit: For C++17 library support we now list which version first added the feature, so you only need to look at the latest docs: https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.201z

FWIW at the moment I'm interrested in <cstdint>, C++11 <cmath> functions and std::hash

They should be present in all versions of libstdc++ that have any C++0x/C++11 support.

like image 34
Jonathan Wakely Avatar answered Oct 20 '22 22:10

Jonathan Wakely