NULL和nullptr

在Clang 6.0 的stddef.h文件中可以找到NULL和nullptr的声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#undef NULL
#ifdef __cplusplus
#  if !defined(__MINGW32__) && !defined(_MSC_VER)
#    define NULL __null
#  else
#    define NULL 0
#  endif
#else
#  define NULL ((void*)0)
#endif
#ifdef __cplusplus
#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
namespace std { typedef decltype(nullptr) nullptr_t; }
using ::std::nullptr_t;
#endif
#endif

早在1972年,C语言诞生的初期,常数0带有常数及空指针的双重身分。 C使用preprocessor macro NULL表示空指针,让NULL及0分别代表空指针及常数0。 NULL可被定义为((void*)0)或是0。

C++并不采用C的规则,不允许将void*隐式转换为其他类型的指针。为了使代码char* c = NULL;能通过编译,NULL只能定义为0。这样的决定使得函数重载无法区分代码的语义:

1
2
void foo(char *);
void foo(int);

C++建议NULL应当定义为0,所以foo(NULL);将会调用foo(int),这并不是程序员想要的行为,也违反了代码的直观性。0的歧义在此处造成困扰。

C++11引入了新的关键字来代表空指针常数:nullptr,将空指针和整数0的概念拆开。 nullptr的类型为nullptr_t,能隐式转换为任何指针或是成员指针的类型,也能和它们进行相等或不等的比较。而nullptr不能隐式转换为整数,也不能和整数做比较。

为了向下兼容,0仍可代表空指针常数。

1
2
3
4
5
char* pc = nullptr;      // OK
int * pi = nullptr;      // OK
int    i = nullptr;      // error
  
foo(pc);            // 呼叫foo(char *)

PS:__MINGW32__是MinGW编译器的预定义宏。_MSC_VER是微软C/C++编译器——cl.exe 编译代码时预定义的一个宏。_MSC_VER的值表示cl的版本。需要针对cl特定版本编写代码时,也可以使用该宏进行条件编译。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值