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