Why are NULL pointers defined differently in C and C++?(为什么 NULL 指针在 C 和 C++ 中的定义不同?)
问题描述
在 C 中,NULL 被定义为 (void *)0 而在 C++ 中它是 0.为什么会这样?在 C 中,我可以理解如果 NULL 没有被类型转换为 (void *) 那么编译器可能会/可能不会产生警告.除此之外,还有什么原因吗?
In C, NULL is defined as (void *)0 whereas in C++ it is 0. Why is it so?
In C I can understand that if NULL is not typecast to (void *) then compilers may/may not generate warning. Other than this, is there any reason?
推荐答案
早在 C++03 中,空指针被 ISO 规范 (§4.10/1) 定义为
Back in C++03, a null pointer was defined by the ISO specification (§4.10/1) as
空指针常量是求值为零的整数类型的整数常量表达式 (5.19) 右值.
A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.
这就是为什么在 C++ 中你可以写
This is why in C++ you can write
int* ptr = 0;
在 C 中,此规则类似,但略有不同 (§6.3.2.3/3):
In C, this rule is similar, but is a bit different (§6.3.2.3/3):
值为 0 的整数常量表达式,或这样的表达式转换为类型void *,称为空指针常量.55) 如果将空指针常量转换为指针类型,结果指针,称为空指针,保证比较不相等指向任何对象或函数的指针.
An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant.55) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.
因此,两者
int* ptr = 0;
和
int* ptr = (void *)0
是合法的.但是,我的猜测是 void* 演员表在这里,所以像
are legal. However, my guess is that the void* cast is here so that statements like
int x = NULL;
在大多数系统上产生编译器警告.在 C++ 中,这是不合法的,因为您不能在没有强制转换的情况下将 void* 隐式转换为另一种指针类型.例如,这是非法的:
produce a compiler warning on most systems. In C++, this wouldn't be legal because you can't implicitly convert a void* to another pointer type implicitly without a cast. For example, this is illegal:
int* ptr = (void*)0; // Legal C, illegal C++
然而,这会导致问题,因为代码
However, this leads to issues because the code
int x = NULL;
是合法的 C++.由于这一点以及随之而来的混乱(以及另一种情况,稍后显示),从 C++11 开始,就有一个关键字 nullptr 表示空指针:
is legal C++. Because of this and the ensuing confusion (and another case, shown later), since C++11, there is a keyword nullptr representing a null pointer:
int* ptr = nullptr;
这没有任何上述问题.
nullptr 比 0 的另一个优点是它在 C++ 类型系统中表现得更好.例如,假设我有这两个功能:
The other advantage of nullptr over 0 is that it plays better with the C++ type system. For example, suppose I have these two functions:
void DoSomething(int x);
void DoSomething(char* x);
如果我打电话
DoSomething(NULL);
相当于
DoSomething(0);
调用 DoSomething(int) 而不是预期的 DoSomething(char*).但是,使用 nullptr,我可以写
which calls DoSomething(int) instead of the expected DoSomething(char*). However, with nullptr, I could write
DoSomething(nullptr);
它会按预期调用 DoSomething(char*) 函数.
And it will call the DoSomething(char*) function as expected.
同样,假设我有一个 vector 并且想要将每个元素设置为空指针.使用 std::fill 算法,我可能会尝试编写
Similarly, suppose that I have a vector<Object*> and want to set each element to be a null pointer. Using the std::fill algorithm, I might try writing
std::fill(v.begin(), v.end(), NULL);
然而,这不会编译,因为模板系统将 NULL 视为 int 而不是指针.为了解决这个问题,我必须写
However, this doesn't compile, because the template system treats NULL as an int and not a pointer. To fix this, I would have to write
std::fill(v.begin(), v.end(), (Object*)NULL);
这很丑陋,并且在某种程度上违背了模板系统的目的.为了解决这个问题,我可以使用 nullptr:
This is ugly and somewhat defeats the purpose of the template system. To fix this, I can use nullptr:
std::fill(v.begin(), v.end(), nullptr);
并且由于已知 nullptr 具有对应于空指针的类型(具体来说,std::nullptr_t),这将正确编译.
And since nullptr is known to have a type corresponding to a null pointer (specifically, std::nullptr_t), this will compile correctly.
希望这有帮助!
这篇关于为什么 NULL 指针在 C 和 C++ 中的定义不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 NULL 指针在 C 和 C++ 中的定义不同?
- STL 中有 dereference_iterator 吗? 2022-01-01
- 从python回调到c++的选项 2022-11-16
- 如何对自定义类的向量使用std::find()? 2022-11-07
- C++ 协变模板 2021-01-01
- 静态初始化顺序失败 2022-01-01
- 近似搜索的工作原理 2021-01-01
- 与 int by int 相比,为什么执行 float by float 矩阵乘法更快? 2021-01-01
- 一起使用 MPI 和 OpenCV 时出现分段错误 2022-01-01
- Stroustrup 的 Simple_window.h 2022-01-01
- 使用/clr 时出现 LNK2022 错误 2022-01-01
