为什么空指针在C和C ++不同的定义? [英] Why are NULL pointers defined differently in C and C++?
问题描述
在C, NULL
定义为(无效*)0
,而在C ++中是 0
。为什么会这样呢?
在C我能理解,如果 NULL
不强制转换为(无效*)
然后编译器可能/可能不会产生警告。除此之外,还有什么原因?
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 ++中,空指针是由ISO规范(宗; 4.10 / 1)定义为
In C++, the null pointer is defined by the ISO specification (§4.10/1) as
一个空指针常量是一个整型常量前pression(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,或者这样的前pression投整型常量前pression键入
无效*
,被称为一个空指针constant.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
是合法的。不过,我的猜测是,无效*
投在这里,使之类的语句
are legal. However, my guess is that the void*
cast is here so that statements like
int x = NULL;
产生在大多数系统上编译器警告。在C ++中,这不会是合法的,因为你不能隐式转换无效*
隐另一个指针类型不进行强制转换。例如,这是非法的:
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++
然而,这将导致问题,因为code
However, this leads to issues because the code
int x = NULL;
是合法的C ++。因为这和随之而来的混乱(和另一种情况,后来所示),C ++ 11现在有一个关键字的 nullptr
重新presenting一个空指针:
is legal C++. Because of this and the ensuing confusion (and another case, shown later), C++11 now has a keyword nullptr
representing a null pointer:
int* ptr = nullptr;
此没有任何的上述问题。
This doesn't have any of the above problems.
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的(字符*)
。然而,随着 nullptr
,我可以写
which calls DoSomething(int)
instead of the expected DoSomething(char*)
. However, with nullptr
, I could write
DoSomething(nullptr);
和它将调用 DoSomething的(字符*)
功能如预期。
And it will call the DoSomething(char*)
function as expected.
同样的,假设我有一个矢量<对象* GT;
并要设置的每个元素是一个空指针。使用的std ::填写
算法,我可能会尝试写
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
A型),这将正确编译。
And since nullptr
is known to have a type corresponding to a null pointer (specifically, std::nullptr_t
), this will compile correctly.
希望这有助于!
这篇关于为什么空指针在C和C ++不同的定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!