Initialization with a null pointer constant: which behavior is correct?

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

Define a standard (C ++ 11 §4.10 / 1)

The null pointer constant is an integral constant expression (5.19) prvalue of an integer type that evaluates to zero or a value of type std::nullptr_t . The null pointer constant can be converted to a pointer type; ...

There are four possibilities:

  • Line 4 is fine, but line 3 is not. This is because x and x+x are constant expressions that evaluate to 0, but only x+x is the prvalue value. Gcc seems to accept this interpretation ( live demo )

  • Lines 3 and 4 are both ok. Although x is an lvalue, the lvalue-to-rvalue conversion is applied, which gives a constant prvalue expression of 0. The clang on my system (clang-3.0) accepts both lines 3 and 4.

  • Lines 3 and 4 are both out of order. clang-3.4 on both lines ( live demo ).

  • Line 3 is fine, but line 4 is not. (Included for the sake of completeness, although not one compiler I tried showed this behavior.)

Who is right? It depends on which version of the standard we are considering?

+6
source share
1 answer

The wording in the standard has changed as a result of DR 903 . New wording

The null pointer constant is an integer literal (2.14.2) with a value of 0 or a value of the class std::nullptr_t .

Problem 903 is related to a curious angular case where it is not possible to create the “correct” overload resolution in some cases where the template parameter is (possibly 0) an integer constant.

Apparently several possible permissions have been considered, but

There is a strong consensus between the CWG that only the literal 0 should be considered a null pointer constant, and not any arbitrary null constant expression that is currently defined.

So, yes, it depends on whether the compiler complied with DR 903 or not.

+10
source

Source: https://habr.com/ru/post/970825/


All Articles