Conversion from null-integer to pointer in comma l

2019-07-16 20:51发布

问题:

I know that in our modern world NULL and 0 are not best practices in operating with pointers, and according to cppreference:

Pointer conversions A null pointer constant (see NULL), can be converted to any pointer type, and the result is the null pointer value of that type. Such conversion (known as null pointer conversion) is allowed to convert to a cv-qualified type as a single conversion, that is, it's not considered a combination of numeric and qualifying conversions.

But why this code is not allowed and gcc with clang give me an error?

A* foo()
{
    return (bar(), NULL);
}

error: invalid conversion from long int to A*

回答1:

The issue here is that

(bar(), NULL)

is an expression using the comma operator.

In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded, and its side effects are completed before evaluation of the expression E2 begins (note that a user-defined operator, cannot guarantee sequencing).

The type, value, and value category of the result of the comma expression are exactly the type, value, and value category of the second operand, E2. If E2 is a temporary, the result of the expression is that temporary. If E2 is a bit-field, the result is a bit-field.

So the type of (bar(), NULL) is being determined as a long int as that is the type of NULL So it is trying to convert a long int with the value of NULL to an A* which will fail.

If we changed the code to

A* foo()
{
    return NULL;
}

This will compile as the value of NULL is used and the value of NULL can be assigned to a pointer.



回答2:

The answer is presented in your question.

A null pointer constant (see NULL), can be converted to any pointer type, and the result is the null pointer value of that type.

NULL is constant, bar(), 0 is not constant.

Just compare:

A* foo()
{
    return 0;
}

versus

A* foo()
{
    int v = 0;
    return v;
}

versus

A* foo()
{
    const int v = 0;
    return v;
}