Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 逗号列表中从空整数到指针的转换_C++_Pointers_Null_C++98 - Fatal编程技术网

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

C++ 逗号列表中从空整数到指针的转换,c++,pointers,null,c++98,C++,Pointers,Null,C++98,我知道在现代世界中,NULL和0不是使用指针操作的最佳实践,根据CPPFREFERENCE: 指针转换空指针常量(请参见null),可以 转换为任何指针类型,结果为空指针 该类型的值。这种转换(称为空指针转换) 允许作为单个转换转换为cv限定类型, 也就是说,它不被认为是数字和限定的组合 转换 但是为什么这段代码是不允许的,gcc和clang会给我一个错误 A* foo() { return (bar(), NULL); } 错误:从long int到A的转换无效* 答案就在你的问题中

我知道在现代世界中,NULL和0不是使用指针操作的最佳实践,根据CPPFREFERENCE:

指针转换空指针常量(请参见null),可以 转换为任何指针类型,结果为空指针 该类型的值。这种转换(称为空指针转换) 允许作为单个转换转换为cv限定类型, 也就是说,它不被认为是数字和限定的组合 转换

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

A* foo()
{
    return (bar(), NULL);
}
错误:从long int到A的转换无效*


答案就在你的问题中

空指针常量(请参见空),可以转换为任何 指针类型,结果是该类型的空指针值

NULL
是常量,
bar(),0
不是常量

比较一下:

A* foo()
{
    return 0;
}

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

A* foo()
{
    int v = 0;
    return v;
}
A* foo()
{
    const int v = 0;
    return v;
}
这里的问题是

(bar(), NULL)
是一个使用

在逗号表达式E1、E2中,表达式E1被求值,其结果被丢弃,其副作用在表达式E2的求值开始之前完成(请注意,用户定义的运算符不能保证排序)

逗号表达式结果的类型、值和值类别正是第二个操作数E2的类型、值和值类别。如果E2是临时的,则表达式的结果就是临时的。如果E2是位字段,则结果是位字段

所以
(bar(),NULL)
的类型被确定为
长int
,因为这是
NULL
的类型,所以它试图将值为
NULL
long int
转换为
a*
,这将失败

如果我们把代码改成

A* foo()
{
    return NULL;
}

这将在使用
NULL
的值时编译,并且
NULL
的值可以分配给指针。

您的意思是gcc中允许的值和clang中的错误吗?请发布完整的代码。我们不知道
A
bar()
是什么,可能有一个重载的
操作符,
,甚至可能有宏使问题更加复杂(事实上,
NULL
是一个宏,所以没有
\include
就不能使用它)。我怀疑编译器正在将NULL转换为与bar的返回类型相同的类型,因为它是逗号表达式的一部分。在最后一个代码段中,v是const,但它不编译。它由GCC C++98编译(请参见问题标签),但它不由C++11编译。这是有意义的。想象代码int a=std::rand();常数int c=a;A*f=c;