Reputation: 38987
I need to backport nullptr to a cross platform library we have, but I'm having trouble getting a reliable check of nullptr support.
Initially I had this:
#if __cplusplus >= 201103L || (__cplusplus < 200000 && __cplusplus >= 199711L)
// nullptr should be ok
#else
// Too old
#endif
But then I discovered that compiling a program that just printed out the value of __cplusplus produced unexpected results.
One blog post claimed 199711L was a value that MS compilers use to indicate partial support for C++11. But I notice g++ 5.4 produces that value by default. Until you expressly tell it to use compile with -std=c++11. But then if you tell it the standard is c++98 the value 199711 is still shown. That doesn't sound right to me. So that's not a good check!
Then I saw someone doing this with an answer that claimed it may work. Well it doesn't.
#if !defined(nullptr)
#endif
But I'm not sure you can do that. So I tested it like this:
#if defined(nullptr)
#error "null ptr defined"
#endif
Guess what? that doesn't print out the error when nullptr is actually available. So that doesn't at all.
How do I detect nullptr or compiler version under linux/windows and OSX (clang)/ android.
Upvotes: 10
Views: 928
Reputation: 304122
Thanks to the hints to the boost library this is what I ended up with. I'm sure I'm not the only one who wants this.
#if defined(__GNUC__)
# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
# define GCC_CXX11
# endif
# if (GCC_VERSION < 40600) || !defined(GCC_CXX11)
# define NO_CXX11_NULLPTR
# endif
#endif
#if defined(_MSC_VER)
# if (_MSC_VER < 1600)
# define NO_CXX11_NULLPTR
# endif
#endif
#if defined(__clang__)
# if !__has_feature(cxx_nullptr)
# define NO_CXX11_NULLPTR
# endif
#endif
#if defined(NO_CXX11_NULLPTR)
# pragma message("Defining nullptr")
# define nullptr 0
#endif
Upvotes: 4
Reputation: 42888
If you're using Boost, Boost.Config provides the BOOST_NO_CXX11_NULLPTR
macro.
Boost implements this by defining it for each compiler-version-combo that doesn't support it, so you cannot easily duplicate the functionality.
If you're using CMake, you can use compiler feature detection (specifically cxx_nullptr
) to conditionally define a macro.
#if !defined(nullptr)
doesn't work because nullptr
is not a macro.
Upvotes: 9