我需要将nullptr backport到我们拥有的跨平台库,但是我无法对nullptr支持进行可靠的检查。
最初我有这个:
#if __cplusplus >= 201103L || (__cplusplus < 200000 && __cplusplus >= 199711L)
// nullptr should be ok
#else
// Too old
#endif
但后来我发现编译一个刚刚打印出__cplusplus值的程序会产生意想不到的结果。
一篇博文称199711L是MS编译器用来表示对C ++ 11的部分支持的值。但我注意到g ++ 5.4默认生成该值。直到你明确告诉它使用-std = c ++ 11编译。 但是如果你告诉它标准是c ++ 98,那么仍然会显示199711的值。这对我来说听起来不对。所以这不是一个好的检查!
然后我看到someone doing this的答案声称它可能有效。嗯,它没有。
#if !defined(nullptr)
#endif
但我不确定你能做到这一点。所以我测试了它:
#if defined(nullptr)
#error "null ptr defined"
#endif
猜猜是什么?当nullptr实际可用时,它不会打印出错误。所以根本就没有。
如何在linux / windows和OSX(clang)/ android下检测nullptr或编译器版本。
答案 0 :(得分:8)
如果您使用的是Boost,Boost.Config会提供BOOST_NO_CXX11_NULLPTR
宏。
Boost通过为每个不支持它的编译器版本组合定义它来实现这一点,因此您无法轻易复制该功能。
如果您使用的是CMake,则可以使用compiler feature detection(具体为cxx_nullptr
)来有条件地定义宏。
#if !defined(nullptr)
不起作用,因为nullptr
不是宏。
答案 1 :(得分:3)
感谢提升库的提示,这就是我最终的结果。我确定我不是唯一一个想要这个的人。
#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