从空整数到逗号列表中的指针的转换

Conversion from null-integer to pointer in comma list

我知道在我们的现代世界中,NULL 和 0 不是使用指针操作的最佳实践,并且根据 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.

但是为什么这个代码是不允许的,gcc with clang 给我一个错误?

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

error: invalid conversion from long int to A*

答案在您的问题中。

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是常数,bar(), 0不是常数。

比较一下:

A* foo()
{
    return 0;
}

对比

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

对比

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

这里的问题是

(bar(), NULL)

是一个使用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.

所以 (bar(), NULL) 的类型被确定为 long int 因为那是 NULL 的类型 所以它试图用值转换 long int NULLA* 会失败。

如果我们将代码更改为

A* foo()
{
    return NULL;
}

这将编译为 NULL 的值被使用并且 NULL 的值可以分配给一个指针。