sizeof(void()) 是一个合法的表达式吗?

Is sizeof(void()) a legal expression?

[5.3.3/1],我发现:

The sizeof operator shall not be applied to an expression that has function or incomplete type

[3.9/5] 我发现:

Incompletely-defined object types and cv void are incomplete types

无论如何,因为 sizeof 不计算它的操作数,我会说 sizeof(void()) 是一个合法的表达式(实际上 GCC 编译它,结果是 1)。
另一方面,从 here 开始,在讨论 sizeof 时未提及 void,无论是在提及大小为 1 的类型时,还是在具有 [=28 的类型的列表中=]实现定义大小。

因此问题是:sizeof(void()) 是一个合法的表达式吗?
是否保证大小等于 1?
或者它是导致 UB 的合法表达式,仅此而已?

通过查看 CppReference.com - sizeof operator,文档字面意思是:

sizeof cannot be used with function types, incomplete types, or bit-field glvalues.

并且由于void()是函数类型,所以sizeof(void())不是合法的表达式。

在他们的用法示例中,我们可以看到他们在这一行的错误评论:

std::cout << "size of function: " << sizeof(void()) << '\n'; // error

void() 是一个函数类型(它是一个不带参数且 returns 什么都没有的函数),所以它在 sizeof().

中不是有效类型

另外,如果你编译代码,比如下面的例子:

#include <iostream>

int main()
{
   std::cout << sizeof(void());
}

代码编译正确并生成值 1,但如果查看编译,您会看到:

main.cpp: In function 'int main()':

main.cpp:5:29: warning: invalid application of 'sizeof' to a function type [-Wpointer-arith]

std::cout << sizeof(void());

因此,很明显 sizeof() 不适用于函数类型,因此代码会产生警告。这是无效的。


Code here


正如这里的文档中所强调的那样http://en.cppreference.com/w/cpp/language/sizeof

备注

sizeof() 不能与 函数类型 、不完整类型或位域泛左值一起使用。

由于void()是函数类型,所以它不是sizeof()

的有效类型

注:

void() 是一个不带参数且 returns 没有任何参数的函数

引用文档中的示例:

//<< "size of function: " << sizeof(void()) << '\n'  // error

所以你的问题的答案:

1)不,这不是一个合法的表达式。

2)它会显示为 1 ,但会显示警告

3)同1).

一个小前提。

这个问题源于对 sizeof 运算符的误解。
事实上,OP 认为 void()sizeof 的上下文中具有不完整类型的表达式,问题本身可以理解为 - 为什么 sizeof 接受表达式 void(),这是一个不完整的类型,不应该像工作草案中提到的那样被接受?
这就是为什么实际上提到[3.9/5],否则就没有意义了。

也就是说,这个问题实际上包含两个有趣的问题:

  • 为什么 sizeof(void()) 不合法?
    这是标题本身的实际问题。

  • 为什么 sizeof((void())) 不合法?
    这是 OP 的预期问题。

以下答案:

  • void() in sizeof(void()) 被解释为函数类型,它是 ill-formed 至于 [5.3.3/1] (强调我的):

    The sizeof operator shall not be applied to an expression that has function or incomplete type, to the parenthesized name of such types, [...]

  • (void()) in sizeof((void())) 是一个不完整类型 void 的表达式(注意 sizeof 是一个未计算的上下文)并且它是 ill-formed至于[5.3.3/1](强调我的):

    The sizeof operator shall not be applied to an expression that has function or incomplete type, to the parenthesized name of such types, [...]

在这两种情况下,GCC 都会编译带有警告的代码。

来自 C99 参考编号的 Straigth

文档中第 6.5.3.4 节所述 sizeof 运算符:

The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member.

根据第 6.2.5 节的第 19 项和第 20 项类型

  1. The void type comprises an empty set of values; it is an incomplete type that cannot be completed.
  2. ...A function type describes a function with specified return type. A function type is characterized by its return type and the number and types of its parameters. A function type is said to be derived from its return type, and if its return type is T, the function type is sometimes called ‘‘function returning T’’. The construction of a function type from a return type is called ‘‘function type derivation’’.

因此 void() 是一个派生自不完整类型的函数类型,它作为 sizeof 的操作数是非法的。那就是说它的 returns 将取决于编译器的实现并且没有任何 return 保证值

C99 Standard