在C++11中,nullptr关键字被添加为一个更类型安全的空指针常量,因为之前NULL作为0的常见定义存在一些问题。为什么标准委员会选择不调用新的空指针常量NULL,或者声明NULL应该是#define d to nullptr?
nullptr
NULL
#define
kx5bkwkv1#
Stephan T. Lavavej(C++标准委员会成员)解释说,一旦在talk(55:35)中:虽然允许#define NULL nullptr的实现,但它会破坏相当多的使用,如
#define NULL nullptr
int i = NULL;
很明显,这样的人很多,所以他们不能强迫改变。
ru9i0ody2#
nullptr是指针类型,而NULL倾向于整型,有时在重载函数中,您需要清楚您使用的是指针而不是整型-这正是nullptr派上用场的时候。因此,要真正回答您的问题,NULL和nullptr有两个不同的用途,将一个重新定义为另一个可能会破坏现有代码库中的许多内容。除此之外,请查看Bjarne Stroustrup的网站:
我应该使用NULL还是0?
在C中,NULL的定义是0,所以只有美学上的区别。我更喜欢避免宏,所以我使用0。NULL的另一个问题是,人们有时会错误地认为它不同于0和/或不是整数。在标准之前的代码中,NULL有时被定义为不合适的东西,因此必须避免。现在这种情况已经不常见了。如果你必须给空指针命名,称之为空指针;在C11中是这么叫的,那么nullptr就是一个关键字。
p8ekf7hl3#
NULL不是类型安全的。由于历史原因,它在没有强制转换的情况下被定义为0,并且编译器对将数字强制转换为此特殊零上的指针的警告静音。对于即时,您可以执行以下操作:
void* p = 0;
但这不是没有隐式强制转换的情况:
void* p = 1234;
副作用是,它可能被滥用为数值,如其他答复所述。nullptr通过强制它是一个指针来改进这一点,你不能把它赋给一个整数。由于行为改变了,为了向后兼容,创建了一个新的名称。还要注意,nullptr由编译器处理,其实际值不会暴露给用户(如NULL为零)。使用架构相关值(如0xdeadbeef)要容易得多,而不会影响程序员的代码逻辑。
0xdeadbeef
5t7ly7z54#
如果没有参加标准委员会的讨论,很难说清楚,但我认为这是因为它会破坏一些使用NULL的代码,而nullptr的含义并不充分兼容。
krcsximq5#
可能是因为新的空指针是关键字,而关键字不能是#defined,所以将其称为NULL会使包含的任何C头都可能是格式错误的。
#defined
标准委员会确实允许NULL为#defined到nullptr,但并不要求这样做。
C++11 18.2类型[支持.类型]/2:宏NULL是本国际标准中实现定义的C空指针常量。**C11 4.10指针转换[转换指针]/1**:一个 *null指针常量 * 是一个整型常量表达式(5.19),它的值是0或者是std::nullptr_t类型的纯右值。
std::nullptr_t
向后兼容性在这里不是一个问题,任何使用NULL的假设它是整数0的一种形式都是不符合标准的。实现可能选择不这样做来宽恕这种邪恶的行为。
0
e4eetjau6#
我将演示一个案例,其中将nullptr定义为不同类型的决定有助于防止bug。考虑以下函数:
void foo(int); void foo(char *); int main() { foo(NULL); // oops }
在C++98中,上面的代码调用了foo(int)函数,因为NULL被替换为0,这很可能不是您想要的。但是如果你调用foo(nullptr),它就会调用正确的函数--*foo(char)**。
dm7nw8vv7#
引入nullptr是为了类型安全和清晰(可能是为了停止使用NULL初始化非指针类型)。NULL(int类型)未更改为nullptr(指针类型),以避免混淆并确保向后兼容性。因此,标准委员会的思路可能与从旧符号到新符号的平稳过渡有关,而不会引起歧义或破坏任何现有代码。
7条答案
按热度按时间kx5bkwkv1#
Stephan T. Lavavej(C++标准委员会成员)解释说,一旦在talk(55:35)中:
虽然允许
#define NULL nullptr
的实现,但它会破坏相当多的使用,如很明显,这样的人很多,所以他们不能强迫改变。
ru9i0ody2#
nullptr
是指针类型,而NULL
倾向于整型,有时在重载函数中,您需要清楚您使用的是指针而不是整型-这正是nullptr
派上用场的时候。因此,要真正回答您的问题,
NULL
和nullptr
有两个不同的用途,将一个重新定义为另一个可能会破坏现有代码库中的许多内容。除此之外,请查看Bjarne Stroustrup的网站:
我应该使用NULL还是0?
在C中,NULL的定义是0,所以只有美学上的区别。我更喜欢避免宏,所以我使用0。NULL的另一个问题是,人们有时会错误地认为它不同于0和/或不是整数。在标准之前的代码中,NULL有时被定义为不合适的东西,因此必须避免。现在这种情况已经不常见了。如果你必须给空指针命名,称之为空指针;在C11中是这么叫的,那么nullptr就是一个关键字。
p8ekf7hl3#
NULL
不是类型安全的。由于历史原因,它在没有强制转换的情况下被定义为0,并且编译器对将数字强制转换为此特殊零上的指针的警告静音。对于即时,您可以执行以下操作:
但这不是没有隐式强制转换的情况:
副作用是,它可能被滥用为数值,如其他答复所述。
nullptr
通过强制它是一个指针来改进这一点,你不能把它赋给一个整数。由于行为改变了,为了向后兼容,创建了一个新的名称。还要注意,
nullptr
由编译器处理,其实际值不会暴露给用户(如NULL
为零)。使用架构相关值(如0xdeadbeef
)要容易得多,而不会影响程序员的代码逻辑。5t7ly7z54#
如果没有参加标准委员会的讨论,很难说清楚,但我认为这是因为它会破坏一些使用
NULL
的代码,而nullptr
的含义并不充分兼容。krcsximq5#
为什么标准委员会选择不调用新的空指针常量
NULL
可能是因为新的空指针是关键字,而关键字不能是
#defined
,所以将其称为NULL
会使包含的任何C头都可能是格式错误的。还是声明
NULL
应为#defined
到nullptr
?标准委员会确实允许
NULL
为#defined
到nullptr
,但并不要求这样做。C++11 18.2类型[支持.类型]/2:宏
NULL
是本国际标准中实现定义的C空指针常量。**C11 4.10指针转换[转换指针]/1**:一个 *null指针常量 * 是一个整型常量表达式(5.19),它的值是0或者是
std::nullptr_t
类型的纯右值。向后兼容性在这里不是一个问题,任何使用
NULL
的假设它是整数0
的一种形式都是不符合标准的。实现可能选择不这样做来宽恕这种邪恶的行为。e4eetjau6#
我将演示一个案例,其中将nullptr定义为不同类型的决定有助于防止bug。
考虑以下函数:
在C++98中,上面的代码调用了foo(int)函数,因为NULL被替换为0,这很可能不是您想要的。
但是如果你调用foo(nullptr),它就会调用正确的函数--*foo(char)**。
dm7nw8vv7#
引入
nullptr
是为了类型安全和清晰(可能是为了停止使用NULL
初始化非指针类型)。NULL
(int类型)未更改为nullptr
(指针类型),以避免混淆并确保向后兼容性。因此,标准委员会的思路可能与从旧符号到新符号的平稳过渡有关,而不会引起歧义或破坏任何现有代码。