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