Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11 backwards compatibility (conversion of null integer constant to pointer)

The C++ standard allows the implicit conversion of zero integer constant to pointer of any type.

The following code is invalid, because the value v is not constant here:

float* foo()
{
    int v = 0;
    return v;    // Error
}

But the following code is correct:

float* foo()
{
    const int v = 0;
    return v;    // Ok in C++98 mode, error in C++11 mode
}

The question is: why gcc and clang (tried different versions) compile the code correctly in c++98/03 mode but return warning/error when compiled in c++11/14 mode (-std=c++11)? I tried to find the changes in C++11 working draft PDF, but got no success.

Intel compiler 16.0 and VS2015 compilers show no errors and warnings in both cases.

like image 206
Andrey Nasonov Avatar asked Nov 11 '15 17:11

Andrey Nasonov


1 Answers

GCC and Clang behave differently with -std=c++11 because C++11 changed the definition of a null pointer constant, and then C++14 changed it again, see Core DR 903 which changed the rules in C++14 so that only literals are null pointer constants.

In C++03 4.10 [conv.ptr] said:

A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.

That allows all sorts of of expressions, as long as they are constant and evaluate to zero. Enumerations, false, (5 - 5) etc. etc. ... this used to cause lots of problems in C++03 code.

In C++11 it says:

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.

And in C++14 it says:

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

This is a much more restrictive rule, and makes far more sense.

like image 174
Jonathan Wakely Avatar answered Sep 28 '22 11:09

Jonathan Wakely