从[5.3.3/1],我发现:
sizeof 运算符不得应用于具有函数或不完全类型的表达式
从 [3.9/5] 我发现:
未完全定义的对象类型和 cv void 是不完全的类型
无论如何,对于sizeof
不评估其操作数,我会说sizeof(void())
是一个合法表达式(实际上 GCC 编译它,结果是 1(。
另一方面,从这里开始,在讨论sizeof
时没有提到void
,无论是在提到大小为 1 的类型时,还是在具有实现定义大小的类型列表中
因此,问题是:sizeof(void())
是一种法律表达吗?
它的大小是否保证等于 1?
还是导致UB的法律表达,仅此而已?
void()
是一个函数类型(它是一个不带参数且不返回任何内容的函数(,因此它在sizeof()
中不是有效的类型。
通过查看 CppReference.com - sizeof 运算符,文档字面意思是:
sizeof
不能与函数类型、不完整类型或 位域gl值。
由于void()
是函数类型,因此sizeof(void())
不是法律表达式。
在他们的使用示例中,我们可以看到他们的错误注释:
std::cout << "size of function: " << sizeof(void()) << 'n'; // error
此外,如果您编译代码,例如以下示例:
#include <iostream>
int main()
{
std::cout << sizeof(void());
}
代码编译正确并生成值 1,但如果您查看编译,您会看到以下内容:
main.cpp:在函数 'int main((' 中:
main.cpp:5:29: 警告:对函数类型"sizeof"的应用无效 [-Wpointer-arith]
std::cout <<sizeof(void(((;
因此,很明显,sizeof()
不适用于函数类型,因此代码会生成警告。它是无效的。
在这里编码
一个小前提。
这个问题源于对sizeof
运营商的误解。
事实上,OP认为void()
sizeof
上下文中具有不完整类型的表达式,问题本身可以理解为-为什么sizeof
接受表达式void()
,这是一个不完整的类型,不应该接受工作草案中提到的?
这就是为什么实际上提到[3.9/5]的原因,否则它就没有意义了。
也就是说,事实是这个问题实际上包含两个有趣的问题:
-
为什么
sizeof(void())
不合法?
这是标题本身的实际问题。 -
为什么
sizeof((void()))
不合法?
这是OP的预期问题。
答案如下:
-
sizeof(void())
中的void()
被解释为函数类型,并且它的格式不正确,如 [5.3.3/1](强调我的(:sizeof 运算符不得应用于具有函数或不完全类型的表达式,也不得应用于 此类类型的括号名称,[...]
-
sizeof((void()))
中的(void())
是一个具有不完整类型void
的表达式(请注意,sizeof
是未计算的上下文(,并且它的格式不正确,如 [5.3.3/1](强调我的(:sizeof 运算符不得应用于具有函数或不完全类型的表达式,也不得应用于此类类型的括号名称,[...]
在这两种情况下,GCC 都会编译带有警告的代码。
正如此处文档中已经强调的那样 http://en.cppreference.com/w/cpp/language/sizeof
笔记
sizeof()
不能与函数类型、不完整类型或位字段 gl值一起使用。
由于void()
是函数类型,因此它不是有效的sizeof()
类型
注意:
void()
是一个不带参数且不返回任何内容的函数
引用文档中的示例:
//<< "size of function: " << sizeof(void()) << 'n' // error
所以回答你的问题:
1(不,这不是法律表达。
2(它将显示为 1 ,但将显示警告
3(同1(。
来自 C99 参考编号的 Straigth
在文档第 6.5.3.4 节 运算符的大小下说明:
sizeof 运算符不得应用于具有函数类型或不完整类型的表达式、此类类型的括号名称或指定位字段成员的表达式。
根据第6.2.5节第19项和第20项,类型:
- void 类型包含一组空值;它是无法完成的不完整类型。
- 。函数类型描述具有指定返回类型的函数。函数类型的特征在于其返回类型及其参数的数量和类型。 函数类型被称为从其返回类型派生,如果其返回类型为 T,则函数类型有时称为"返回 T"的函数。从返回类型构造函数类型称为"函数类型派生"。
因此,void(( 是一个派生自不完整类型的函数类型,其作为 size 的操作数是非法的。也就是说,它的返回将取决于编译器实现,并且没有任何返回值保证
C99 标准