NULL 宏实际上可以是 nullptr 吗?
Can the NULL macro actually be a nullptr?
根据标准N4713(7.11/1)草案:
A null pointer constant is an integer literal (5.13.2) with value zero or a prvalue of type std::nullptr_t
.
和 21.2.3/2:
The macro NULL
is an implementation-defined null pointer constant.
按照NULL
可以定义为nullptr
。 cppreference:
中也提到了同样的内容
#define NULL 0
//since C++11
#define NULL nullptr
同时"Additive operators"子句说(8.5.6/7):
If the value 0
is added to or subtracted from a null pointer value, the result is a null pointer value. If two null
pointer values are subtracted, the result compares equal to the value 0
converted to the type std::ptrdiff_t
.
因此下面的代码应该是有效的:
0 + nullptr;
nullptr - nullptr;
但由于缺少 std::nullptr_t
的 +/- 运算符,code is invalid.
有什么我没有考虑到的,或者 NULL
宏实际上不能定义为 nullptr
吗?
虽然nullptr
是空指针常量,但它不是空指针值。后者是一些指针类型的值,std::nullptr_t
不是。
参考:
A null pointer constant is an integer literal (5.13.2) with value zero or a prvalue of type std::nullptr_t
. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is
distinguishable from every other value of object pointer or function pointer type. Such a conversion is called
a null pointer conversion. [...]
7.11/1 in N4659,强调我的
所以 NULL
确实可以 nullptr
而无需提供算术运算符。
关键字nullptr
表示指针字面量。它是 std::nullptr_t
类型的 prvalue
。存在从 nullptr
到任何指针类型的空指针值和任何指向成员类型的指针的隐式转换。
nullptr
本身既不是指针值也不是指针。因此算术运算不适用于nullptr
.
nullptr
是空指针字面量,虽然nullptr
转为指针类型的结果是空指针值,但nullptr
本身并不是指针类型,但类型为 std::nullptr_t
。如果您将 nullptr
转换为指针类型,则该算法有效:
0 + (int*)nullptr;
(int*)nullptr - (int*)nullptr;
Can the NULL macro actually be a nullptr?
是的,因为 nullptr
是空指针文字。
请注意,在 C++11 之前,C++ 中的所有空指针文字恰好也是整数文字,所以这个糟糕的代码:char c = NULL;
曾经在实践中起作用。如果 NULL
定义为 nullptr
,则该代码不再有效。
For addition, either both operands shall have arithmetic or unscoped enumeration type, or one operand shall be a pointer to a completely-defined object type and the other shall have integral or unscoped enumeration type.
For subtraction, one of the following shall hold:
(2.1) both operands have arithmetic or unscoped enumeration type; or
(2.2) both operands are pointers to cv-qualified or cv-unqualified versions of the same completely-defined object type; or
(2.3) the left operand is a pointer to a completely-defined object type and the right operand has integral or unscoped enumeration type.
std::nullptr_t
是其中的 none,因此 std::nullptr
无法参与加法运算。
注意,并不是所有的指针值都可以参与。例如,函数指针值和 void 指针值不能,即使它们都可以是空指针值。
根据标准N4713(7.11/1)草案:
A null pointer constant is an integer literal (5.13.2) with value zero or a prvalue of type
std::nullptr_t
.
和 21.2.3/2:
The macro
NULL
is an implementation-defined null pointer constant.
按照NULL
可以定义为nullptr
。 cppreference:
#define NULL 0
//since C++11
#define NULL nullptr
同时"Additive operators"子句说(8.5.6/7):
If the value
0
is added to or subtracted from a null pointer value, the result is a null pointer value. If two null pointer values are subtracted, the result compares equal to the value0
converted to the typestd::ptrdiff_t
.
因此下面的代码应该是有效的:
0 + nullptr;
nullptr - nullptr;
但由于缺少 std::nullptr_t
的 +/- 运算符,code is invalid.
有什么我没有考虑到的,或者 NULL
宏实际上不能定义为 nullptr
吗?
虽然nullptr
是空指针常量,但它不是空指针值。后者是一些指针类型的值,std::nullptr_t
不是。
参考:
A null pointer constant is an integer literal (5.13.2) with value zero or a prvalue of type
std::nullptr_t
. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion. [...]
7.11/1 in N4659,强调我的
所以 NULL
确实可以 nullptr
而无需提供算术运算符。
关键字nullptr
表示指针字面量。它是 std::nullptr_t
类型的 prvalue
。存在从 nullptr
到任何指针类型的空指针值和任何指向成员类型的指针的隐式转换。
nullptr
本身既不是指针值也不是指针。因此算术运算不适用于nullptr
.
nullptr
是空指针字面量,虽然nullptr
转为指针类型的结果是空指针值,但nullptr
本身并不是指针类型,但类型为 std::nullptr_t
。如果您将 nullptr
转换为指针类型,则该算法有效:
0 + (int*)nullptr;
(int*)nullptr - (int*)nullptr;
Can the NULL macro actually be a nullptr?
是的,因为 nullptr
是空指针文字。
请注意,在 C++11 之前,C++ 中的所有空指针文字恰好也是整数文字,所以这个糟糕的代码:char c = NULL;
曾经在实践中起作用。如果 NULL
定义为 nullptr
,则该代码不再有效。
For addition, either both operands shall have arithmetic or unscoped enumeration type, or one operand shall be a pointer to a completely-defined object type and the other shall have integral or unscoped enumeration type.
For subtraction, one of the following shall hold:
(2.1) both operands have arithmetic or unscoped enumeration type; or
(2.2) both operands are pointers to cv-qualified or cv-unqualified versions of the same completely-defined object type; or
(2.3) the left operand is a pointer to a completely-defined object type and the right operand has integral or unscoped enumeration type.
std::nullptr_t
是其中的 none,因此 std::nullptr
无法参与加法运算。
注意,并不是所有的指针值都可以参与。例如,函数指针值和 void 指针值不能,即使它们都可以是空指针值。