C++ sizeof(void())是合法表达式吗?
从中,我发现: sizeof运算符不得应用于具有函数或不完整类型的表达式 从中我发现: 定义不完整的对象类型和cv void是不完整的类型 无论如何,因为C++ sizeof(void())是合法表达式吗?,c++,language-lawyer,sizeof,void,C++,Language Lawyer,Sizeof,Void,从中,我发现: sizeof运算符不得应用于具有函数或不完整类型的表达式 从中我发现: 定义不完整的对象类型和cv void是不完整的类型 无论如何,因为sizeof不计算它的操作数,我会说sizeof(void())是一个合法的表达式(实际上是GCC编译的,结果是1)。 另一方面,在讨论sizeof时,从中没有提到void,也没有提到大小为1的类型,也没有提到具有实现定义大小的类型列表 因此问题是:sizeof(void()) 是否保证大小等于1? 或者这是一个导致UB的法律表达,仅此而已?从
sizeof
不计算它的操作数,我会说sizeof(void())
是一个合法的表达式(实际上是GCC编译的,结果是1)。另一方面,在讨论
sizeof
时,从中没有提到void
,也没有提到大小为1的类型,也没有提到具有实现定义大小的类型列表
因此问题是:sizeof(void())
是否保证大小等于1?或者这是一个导致UB的法律表达,仅此而已?从字面上看,文档说明:
sizeof
不能与函数类型、不完整类型或
位字段值
既然void()
是函数类型,那么sizeof(void())
就不是合法的表达式
在他们的用法示例中,我们可以在这一行看到他们的错误注释:
std::cout << "size of function: " << sizeof(void()) << '\n'; // error
std::coutvoid()
是一个函数类型(它是一个不带参数且不返回任何内容的函数),因此如果编译代码,它在sizeof()
中也不是有效的类型,例如下面的示例:
#include <iostream>
int main()
{
std::cout << sizeof(void());
}
#包括
int main()
{
std::cout已在此处的文档中突出显示
注释
sizeof()
不能与函数类型、不完整类型或位字段值一起使用
由于void()
是函数类型,因此它不是有效的sizeof()
注:
void()
引用文档中的一个示例:
//<< "size of function: " << sizeof(void()) << '\n' // error
/一个小前提
这个问题源于对sizeof
运算符的误解。
事实上,OP认为void()
是一个在sizeof
上下文中类型不完整的表达式,问题本身可以理解为-whysizeof
接受表达式void()
,这是一个不完整的类型,不应该像工作草案中提到的那样被接受?
这就是为什么会提到[3.9/5],否则就没有意义了
也就是说,事实上这个问题实际上包含两个有趣的问题:
- 为什么
sizeof(void())
不合法?
这是从标题本身来看的实际问题
- 为什么
sizeof((void())
不合法?
这是OP的预期问题
答复如下:
sizeof(void())
中的void()
被解释为函数类型,它的格式与(emphasis mine)相同:
sizeof运算符不得应用于具有函数类型或不完整类型的表达式,也不得应用于此类类型的括号名称
,[…]
sizeof((void())
中的(void())
是一个类型不完整的表达式void
(请注意,sizeof
是一个未计算的上下文),它的格式与(我的强调部分)相同:
sizeof运算符不得应用于具有函数或不完整类型的表达式,也不得应用于此类类型的括号名称[…]
在这两种情况下,GCC都会编译带有警告的代码。从C99参考号开始
第6.5.3.4节下的文件中规定了运营商的规模:
sizeof运算符不得应用于具有函数类型或不完整类型的表达式、此类类型的括号名称或指定位字段成员的表达式
根据第6.2.5节第19项和第20项,类型:
void类型包含一组空值;它是一个不完整的类型,无法完成
…函数类型描述具有指定返回类型的函数。函数类型以其返回类型及其参数的数量和类型为特征。
函数类型称为从其返回类型派生,如果其返回类型为T,则函数类型有时称为“函数返回T”。从返回类型构造函数类型称为“函数类型派生”
因此,void()是从不完整类型派生的函数类型,它作为sizeof的操作数是非法的。也就是说,它的返回将取决于编译器实现,并且不保证有任何返回值
说这是一个错误GCC过去有(可能现在仍然有)扩展,其中sizeof(void)==1
我的g++副本说:警告:“sizeof”对函数类型的应用无效[-Wpointer arith]
应用程序可能会抑制错误/警告messages@skypjack答案是相同的-因此不是。它不是在decltype(void())
中解释的(注意,在这种情况下它不是函数类型)?我真的会这么说。为什么它们不同?@skypjack当你使用带有decltype
的函数类型时,它给出了返回类型的类型。在void()
的情况下,返回类型是void
所以这就是decltype(void())
的类型。那么为什么decltype(void(void))呢
不起作用,以及decltype(int(int))
?不,使用decltype
时,它不是函数类型。在sizeof
的情况下,我不能说。@skypjack我想我现在明白了,decltype
需要一个表达式,而不是一个类型。void()
在这里实际上不是一种类型,而是一种表达式,一种C样式转换(j