简体   繁体   English

这些空指针,还是地址为0的指针?

[英]Are these null pointers, or are they pointers to address 0?

If I write 如果我写

int zero = 0;

void *p1 = (void *)0;
void *p2 = (void *)(int)0;
void *p3 = (void *)(0 /*no-op, but does it affect the next zero?*/, 0);

void *p4 = (void *)zero;    // For reference, this is a pointer to address zero
void *p5 = 0;               // For reference, this is a null pointer
void *p6 = NULL;            // For reference, this is a null pointer
void *p7 = nullptr;         // For reference, this is a null pointer (C++11)

static const int static_zero_1 = 0;       // Is this a literal zero when used?
static const int static_zero_2 = 1 - 1;   // No "literals 0" per se... is it?
void *p8 = (void *)static_zero_1;   // I have seen weird substitution rules...
void *p9 = (void *)static_zero_2;   // do they apply for NULL too?

which of p1 , p2 , and p3 ( edit: I added p8 and p9 ) would be null pointers (ie == NULL , may or may not be address zero), and which of them would be pointers with the address zero (may or may not be == NULL )? p1p2p3哪一个( 编辑:我添加了p8p9 )将是空指针 (即== NULL ,可能或可能不是地址为零),以及它们中的哪一个是地址为零的指针(可以或可能不是== NULL )?

If the answer is different in C and C++, what is it in each of them? 如果答案在C和C ++中有所不同,那么它们中的每一个是什么?

And to make Andy's answer complete with C: 并用C完成Andy的答案:

From the C99 Standard : 从C99标准

6.3.2.3 Pointers 6.3.2.3指针

1 A pointer to void may be converted to or from a pointer to any incomplete or object type. 1指向void的指针可以转换为指向任何不完整或对象类型的指针。 A pointer to any incomplete or object type may be converted to a pointer to void and back again; 指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; the result shall compare equal to the original pointer. 结果应该等于原始指针。

3 An integer constant expression with the value 0 , or such an expression cast to type void * , is called a null pointer constant . 3 值为0整型常量表达式或类型为void *的表达式称为空指针常量 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. 55)如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与指向任何对象或函数的指针进行比较。

So any integer constant expression which evaluates to 0 is a null pointer constant and can be converted to a NULL pointer. 因此,任何求值为0 整型常量表达式都是空指针常量,可以转换为NULL指针。 Effectively in your example, all pointers through except p4 , p8 and p9 are null pointers. 在你的例子中,除了p4p8p9之外的所有指针都是空指针。 p4 , p8 and p9 need not be null pointers since their initialization is not a constant expression because it contains variables (even if const qualified). p4p8p9不需要是空指针,因为它们的初始化不是常量表达式,因为它包含变量(即使const限定)。

Here's another answer about NULL in C++ , for the record. 这是关于C ++中NULL的另一个答案 ,用于记录。

which of p1 , p2 , and p3 would be null pointers? p1p2p3哪一个是空指针?

In C++11, all of them. 在C ++ 11中,所有这些。 Per paragraph 4.10/1 of the C++11 Standard: 根据C ++ 11标准的第4.10 / 1段:

A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t . 空指针常量是整数类型的整数常量表达式(5.19)prvalue,其计算结果为零或类型为std::nullptr_t [...] [...]

Therefore, according to the terminology of the Standard, everything which is a constant (integral) expression and evaluates to 0 is a null pointer constant (not a null pointer , yet). 因此,根据标准的术语,作为常量 (整数)表达式并且求值为0都是空指针常量 (还不是空指针 )。 The only one which is not a constant expression that evaluates to 0 or a prvalue of type nullptr_t in your example is zero , because it is not a constant expression. 在示例中,唯一不是求值为0的常量表达式或类型为nullptr_t的prvalue的值zero ,因为它不是常量表达式。

The paragraph continues: 该段继续:

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 . 这种转换称为空指针转换 Two null pointer values of the same type shall compare equal. 相同类型的两个空指针值应相等。

So in your example all the pointers except p4 are null pointer values and compare equal among themselves. 因此在您的示例中,除p4之外的所有指针都是空指针值,并且它们之间的比较相等。

p1 and p2 are null pointers; p1p2是空指针; p3 is implementation defined, and may be something else. p3是实现定义的,可能是其他东西。 (A comma operator cannot be part of a constant expression. And the mapping of a non-constant integral value 0 to a pointer is implementation defined.) C is identical to C++ here. (逗号运算符不能是常量表达式的一部分。并且非常量整数值0到指针的映射是实现定义的。)C与此处的C ++相同。

p8 and p9 are both null pointers in C++, but not in C. p8p9都是C ++中的空指针,但不是C.

With regards to your comment on static_zero_2 , there is no requirement in either language that a literal zero be present, anywhere. 关于你对static_zero_2的评论,在任何一种语言中都没有要求在任何地方都存在文字零。 g++ defines NULL as the compiler built-in __null , for example, and you can use (1 - 1) , or '\\0' , or any other constant expression evaluating to 0. 例如,g ++将NULL定义为编译器内置的__null ,您可以使用(1 - 1)'\\0' ,或任何其他常量表达式求值为0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM