NULL宏实际上可以是nullptr吗?

时间:2018-02-21 10:50:09

标签: c++ null language-lawyer nullptr

根据标准N4713(7.11 / 1)的草案:

  

空指针常量是一个整数文字(5.13.2),其值为零或prvalue类型为std::nullptr_t

和21.2.3 / 2:

  

NULL是一个实现定义的空指针常量。

关注NULL可以定义为nullptrcppreference上提到了相同的内容:

#define NULL 0
//since C++11
#define NULL nullptr

同时“Additive operators”子句说(8.5.6 / 7):

  

如果将值0添加到空指针值或从空指针值中减去,则结果为空指针值。如果两个为null   减去指针值,结果比较等于转换为0类型的值std::ptrdiff_t

因此以下代码应该有效:

0 + nullptr; 
nullptr - nullptr; 

但由于std::nullptr_t code is invalid缺少+/-运算符。

是否存在我未考虑的内容或NULL宏无法实际定义为nullptr

4 个答案:

答案 0 :(得分:47)

虽然nullptr是空指针常量,但它不是空指针。后者是某种指针类型的值,std::nullptr_t不是。

参考:

  

空指针常量是整数文字(5.13.2),其值为零或prvalue类型为std::nullptr_t空指针常量可以转换为指针类型;结果是该类型的空指针值并且是   可与对象指针或函数指针类型的每个其他值区分开来。这种转换被称为   空指针转换。 [...]

7.11 / 1在N4659中,强调我的

所以NULL确实可以nullptr而不提供算术运算符。

答案 1 :(得分:7)

nullptr是一个空指针文字,虽然将nullptr转换为指针类型的结果是空指针值,但nullptr本身并不是指针类型,但类型为std::nullptr_t。如果您将nullptr转换为指针类型,则算法有效:

0 + (int*)nullptr; 
(int*)nullptr - (int*)nullptr;
  

NULL宏实际上可以是nullptr吗?

是的,因为nullptr是一个空指针文字。

请注意,在C ++ 11之前,C ++中的所有空指针文字也恰好是整数文字,所以这个错误的代码:char c = NULL;曾经在实践中工作。如果NULL定义为nullptr,则该代码不再有效。

答案 2 :(得分:6)

  

另外,两个操作数都应具有算术或非范围的枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整数或无范围的枚举类型。

     

对于减法,以下之一应保持:
  (2.1)两个操作数都有算术或无范围的枚举类型;或
  (2.2)两个操作数都是指向同一个完全定义的对象类型的cv-qualified或cv-nonqualified版本的指针;或
  (2.3)左操作数是指向完全定义的对象类型的指针,右操作数具有整数或未操作的枚举类型。

std::nullptr_t不属于这些,因此std::nullptr不能参与加法运算。

请注意,即使所有指针值都不能参与。例如,函数指针值和void指针值不能,即使其中任何一个都可以是空指针值。

答案 3 :(得分:5)

关键字nullptr表示指针文字。它是prvalue类型的std::nullptr_t。存在从nullptr到任何指针类型的空指针值以及指向成员类型的任何指针的隐式转换。 nullptr本身不是指针值也不是指针。因此算术运算不适用于nullptr