Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialization by null pointer constant: which behaviour is correct?

int main() {
    const int x = 0;
    int* y = x;   // line 3
    int* z = x+x; // line 4
}

Quoth the 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. A null pointer constant can be converted to a pointer type; ...

There are four possibilities:

  1. Line 4 is OK, but line 3 isn't. This is because x and x+x are both constant expressions that evaluate to 0, but only x+x is a prvalue. It appears that gcc takes this interpretation (live demo)

  2. Lines 3 and 4 are both OK. Although x is an lvalue, the lvalue-to-rvalue conversion is applied, giving a prvalue constant expression equal to 0. The clang on my system (clang-3.0) accepts both lines 3 and 4.

  3. Lines 3 and 4 are both not OK. clang-3.4 errors on both lines (live demo).

  4. Line 3 is OK, but line 4 isn't. (Included for the sake of completeness even though no compiler I tried exhibits this behaviour.)

Who is right? Does it depend on which version of the standard we are considering?

like image 241
Brian Bi Avatar asked Jun 14 '14 02:06

Brian Bi


People also ask

How do you initialize an int pointer with 0 and null?

You can use 0 and NULL to initialize the int pointer in line 12 and 13. But if you use the values 0 and NULL as arguments of the function template, the compiler will loudly complain. The compiler deduces 0 in the function template to type int; it deduces NULL to the type long int.

What do C standards say about null pointer?

Let us see what C standards say about null pointer. From C11 standard clause 6.3.2.3, “ An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.

What is a 0 pointer in C?

NULL pointer in C. “ An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. 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.

How does a null pointer behave like a Boolean?

The null pointer constant behaves like a boolean value that initialized with false. You can observe that in lines 22 - 25. If the nullptr has to decide between a long int and a pointer, it will decide for a pointer (line 28). Here is the output of the program.


1 Answers

The wording in the standard changed as a result of DR 903. The new wording is

A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t.

Issue 903 involves a curious corner case where it is impossible to produce the "correct" overload resolution in certain cases where a template parameter is a (possibly 0) integer constant.

Apparently a number of possible resolutions were considered, but

There was a strong consensus among the CWG that only the literal 0 should be considered a null pointer constant, not any arbitrary zero-valued constant expression as is currently specified.

So, yes, it depends on whether the compiler has implemented the resolution to DR 903 or not.

like image 88
rici Avatar answered Sep 18 '22 03:09

rici