Domanda

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 (i.e. == 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)?

If the answer is different in C and C++, what is it in each of them?

È stato utile?

Soluzione 2

p1 and p2 are null pointers; p3 is implementation defined, and may be something else. (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.

p8 and p9 are both null pointers in C++, but not in C.

With regards to your comment on static_zero_2, there is no requirement in either language that a literal zero be present, anywhere. 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.

Altri suggerimenti

And to make Andy's answer complete with C:

From the C99 Standard:

6.3.2.3 Pointers

1 A pointer to void may be converted to or from a pointer to any incomplete or object type. A pointer to any incomplete or object type may be converted to a pointer to void and back again; 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. 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.

So any integer constant expression which evaluates to 0 is a null pointer constant and can be converted to a NULL pointer. Effectively in your example, all pointers through except p4, p8 and p9 are null pointers. 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).

Here's another answer about NULL in C++, for the record.

which of p1, p2, and p3 would be null pointers?

In C++11, all of them. Per paragraph 4.10/1 of the C++11 Standard:

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. [...]

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). 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.

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top