Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I reliably detect support for nullptr?

Tags:

c++

c++11

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.

like image 204
hookenz Avatar asked Feb 22 '17 20:02

hookenz


People also ask

Is nullptr equal to null C++?

nullptr is a new keyword introduced in C++11. nullptr is meant as a replacement to NULL . nullptr provides a typesafe pointer value representing an empty (null) pointer.

How do you define a nullptr?

The nullptr keyword represents a null pointer value. Use a null pointer value to indicate that an object handle, interior pointer, or native pointer type does not point to an object. Use nullptr with either managed or native code.


2 Answers

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

like image 119
emlai Avatar answered Sep 18 '22 09:09

emlai


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
like image 30
Barry Avatar answered Sep 20 '22 09:09

Barry