Determine whether thread_local keyword is supported on compile time - c++

I would like to use thread_local keyword in my project. However, not all the compiler that supports -std=c++11 supports thread_local. Can I know whether there's a way to determine whether thread_local is supported on compile time? I tried googling it but didn't find the answer.

However, not all the compiler that supports -std=c++11 supports thread_local.
According to this reference they need to, to be c++11 standard compliant.
So your question basically boils down to determine if parts of your code are compiled with the -std=c++11 option or not, which is already well answered here.
If you see differences with particular OS environments/C++ Compiler implementations, I'd recommend to run a pre-compilation script, that probes for particular compiler capabilities, and generate a config.h header for you.
Including this header can be used to determine, if particular features are available and you can place appropriate
#if defined(FEATURE)
// feature specific code
#else
// plain code
#endif
in your header and source files.
To support the latter option I have introduced, there are the GNU automake tools, which support to generate such probing script. It's available to support a broad variety of target platforms.

Related

Why does g++ 4.9.0 have std::isnan by default?

My understanding is that the function std::isnan is only available from C++11 onwards. Further, g++ uses -std=gnu++98 unless specifically told not to.
So why does this compile?
>> cat test.cpp
#include <cmath>
int main(int argc, char** argv)
{
return std::isnan(0);
}
>> g++ test.cpp
Is there a flag to take the function out of <cmath>?
Compiler developers are lazy about exactly removing every feature that should only be available in the next version of the standard, especially when related libraries (C99) have it at the same time.
The utility (of validing your code actually obeys a specific standard) is not high enough for compiler writers to work extremely hard at making their compiler provide that service.
Instead, what usually happens is new features are implemented under specific standard flags. Sometimes they are accidentally backported. When the standard finalizes, the partial implementation exists for a while until it gets good enough.
Then work starts on the next version of the standard. The next version flag gives you a less stable development environment, as new features are tried out and discarded and changed.
Some effort it put into not backporting stuff, but it isn't a showstopper.
This is a long-standing issue, documented in the FAQ but in a way that you wouldn't necessarily be able to make sense of.
4.3. _XOPEN_SOURCE and _GNU_SOURCE are always defined?
On Solaris, g++ (but not gcc) always defines the preprocessor macro _XOPEN_SOURCE. On GNU/Linux, the same happens with _GNU_SOURCE. (This is not an exhaustive list; other macros and other platforms are also affected.)
These macros are typically used in C library headers, guarding new versions of functions from their older versions. The C++98 standard library includes the C standard library, but it requires the C90 version, which for backwards-compatibility reasons is often not the default for many vendors.
More to the point, the C++ standard requires behavior which is only available on certain platforms after certain symbols are defined. Usually the issue involves I/O-related typedefs. In order to ensure correctness, the compiler simply predefines those symbols.
Note that it's not enough to #define them only when the library is being built (during installation). Since we don't have an 'export' keyword, much of the library exists as headers, which means that the symbols must also be defined as your programs are parsed and compiled.
To see which symbols are defined, look for CPLUSPLUS_CPP_SPEC in the gcc config headers for your target (and try changing them to see what happens when building complicated code). You can also run g++ -E -dM - < /dev/null" [sic] to display a list of predefined macros for any particular installation.
This has been discussed on the mailing lists quite a bit.
This method is something of a wart. We'd like to find a cleaner solution, but nobody yet has contributed the time.
To explain:
glibc is what provides the standard C library. It supports several modes.
It supports various strict C modes and strict POSIX modes. In these modes, when only standard headers are included, only standard functions are available. In C90 mode, this does not include isnan.
It supports various extension modes. In these modes, non-standard functions are also available. In C90 + extensions mode, this includes isnan. The _GNU_SOURCE preprocessor macro is the one that enables all extensions.
libstdc++ is what provides the standard C++ library. It requires more from glibc than what strict C90 mode offers. Therefore, there are only two options: either libstdc++ does not offer those standard C++ features it cannot provide, or libstdc++ forcibly enables glibc's extensions even in strict ANSI mode. Both mean a failure to conform to the C++ standard, but the former restricts features, while the latter provides them. The latter is seen as the lesser evil.
The only reasonable way to fix this is for glibc to provide some non-standard way to access its extensions even in strict ANSI mode. No such way exists yet, and until such a way is created, non-standard names will be available even in meant-to-be-standard C++ compilation modes.

Apply language standard to just part of a source file?

Is it possible to enforce a C or C++ language standard for just part of a source file? I want to ensure that my source file is C90 compliant, but it depends on some headers that require C99. The compliance of those headers isn't important to me right now (I can compile with C99 for the time being), but I want to minimize effort required to port my code to a more restrictive platform in the future.
In short, I want a language standard to apply to the entire file except for the included headers. Given how header inclusion works in C and C++, I figure that the general problem is to apply a language standard to an arbitrary portion of a given source file.
I'm working with GCC in particular, but I'm also curious if this is possible with other compilers (msvc, clang).
If you want to make sure your code is C90 compatible while still relying on headers that use C99, you can enable the GCC warning flag -Wc90-c99-compat. This allows you to use C99 features, but emits a warning wherever you use features not available in C90. To avoid generating these warnings in your header files (which are presumably correct), enable the warning using a pragma, after you include the files.
This will basically achieve what you want. The warnings will only be emitted for the code you specify.
#include "myheader.h"
#pragma GCC diagnostic warning "-Wc90-c99-compat"
void func(void) { ... }
A stricter version would be to use:
#pragma GCC diagnostic error "-Wc90-c99-compat"
As far as I know, Clang is mostly compatible, but MSVC doesn't really support C99 that well to begin with so you're on your own.
No. You cannot build a file (compilation unit) as partly one language standard and partly another.
What you can do however is split the file into two files and compile each of them using different language standards (just be sure that it is then still well defined to link both object files afterwards).
A better solution would be to ensure that all the code complies with the newer or older language standard and then just use that.

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).
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?
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.
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.
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.

Is there a preprocessor directive for detecting C++11x support? [duplicate]

This question already has answers here:
How do I check for C++11 support?
(9 answers)
Closed 9 years ago.
If have some code where I would like to use C++11x extensions as much as possible, but have a fallback if this is not supported. Currently the OSX version of GCC and the VisualC compiler has little to no support for C++11x, so I use:
#if (defined(__APPLE__) || (defined(_WIN32)))
...fallback code without C++11x ...
#else
... code using C++11x ...
#endif
And this works, but is not really the right thing to do, especially since the gcc compiler in MacPorts DOES support c++11x.
Is there a #define C11X_SUPPORTED type macro? Perhaps something only GCC has?
__cplusplus should be defined as 199711L in pre-C++11 compilers, 201103L in those suporting C++11. Whether this is much help in practice is another question: most compilers are only halfway there, so shouldn't be defining it as 201103L, even if they support the features you are interested in. And it's not unheard of for a compiler to lie: a compiler which defines it as 199711L and doesn't support export for templates, for example. But there's no standard feature by feature test.
The simplest solution is just not to use any particular new feature until you can be sure that all compilers support it. You have to write and support the fallback code anyway; why maintain two versions. The one exception to this rule might be new features which impact on performance: whether the compiler supports move semantics or not. In such cases, I'd suggest a compiler dependent include file, which you write yourself based on the compiler documentation and personal tests; just because the compiler may document that it supports a specific feature doesn't mean that its support is bug-free. Just create a directory per targeted compiler, put this file there and specify the appropriate -I or /I option in your makefile or project file.
And your tests should be something along the lines of:
#ifdef HAS_MOVE_SEMANTICS
...
#endif
rather than just on the compiler, version or whatever.
You can check the value of the __cplusplus macro. For C++11, it's greater than 199711L.
So something like
#if __cplusplus > 199711L
#endif
The Boost.Config library provides granular preprocessor macros you can use to conditionally compile based on the presence of a given C++11 feature.
(For a compiler, C++11 support need not be an all or nothing proposition. For example, consider how Microsoft cherry picked which C++11 features to include in Visual Studio 2012 based on what they believed would most benefit their customers.)

What are the differences between -std=c++11 and -std=gnu++11?

What are the differences between -std=c++11 and -std=gnu++11 as compilation parameter for gcc and clang? Same question with c99 and gnu99? I know about C++ and C standards, it's the differences in the parameters that interest me.
I've read somewhere that it has to do with some extensions but it is not clear to me which ones and how to choose between one or the other for a new project.
As you have found out yourself, the difference between the two options is whether GNU extensions that violates/extend the C++ standard are enabled or not. The GNU C++ extensions are described here. You can also use most of the GNU C extensions (described here) in your C++ programs. It would be also useful to read about the -Wpedantic GCC option here.
Note that some extensions can still be in effect when using -std=c++11, as long as they do not contradict the standard. For instance, when using the MinGW compiler, I need the extensions for a working Boost.Lexical_Cast. But, as long as you don't use any of them, you are better off sticking to the standard without extensions for maximum portability. This might come in handy if you find yourself forced to change compiler.