Is sizeof(void()) a legal expression?

From [5.3.3/1], I found that:

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

From [3.9/5] I found that:

Incompletely-defined object types and cv void are incomplete types

Anyway, for sizeof does not evaluate it's operands, I would have said that sizeof(void()) was a legal expression (actually GCC compiles it and the result is 1).
On the other side, from here, void is not mentioned while discussing sizeof, neither when the types having size 1 are mentioned, nor in the list of the ones having an implementation defined size.

The question is thus: is sizeof(void()) a legal expression?
Is it guaranteed to have size equal to 1?
Or is it a legal expression resulting in an UB and that's all?


Solution 1:

void() is a function type (it's a function which takes no arguments and returns nothing), so it's not a valid type in sizeof().

Solution 2:

From looking at CppReference.com - sizeof operator, the documentation literally states:

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

And since void() is a function type, then sizeof(void()) is not a legal expression.

In their usage example, we can see their error comment on this line:

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

Solution 3:

Also, if you compile the code, such as the example below:

#include <iostream>

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

The code compiles correctly and produces a value of 1, but if you look at the compilation, you see this:

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());

So, it is evident that sizeof() doesn't apply for function types, so the code produces a warning. It is invalid.


Code here

Solution 4:

A little premise.

The question arose from a misinterpretation of the sizeof operator.
In fact the OP considered void() an expression that has incomplete type in the context of sizeof and the question itself can be read as - why sizeof accept the expression void(), that is an incomplete type and should not be accepted as mentioned in the working draft?
That's why [3.9/5] is mentioned actually, otherwise it wouldn't have made sense.

That said, the fact is that the question contains actually two interesting questions:

  • Why is sizeof(void()) not legal?
    This is the actual question as from the title itself.

  • Why is sizeof((void())) not legal?
    This is the intended question of the OP.

Answers below:

  • void() in sizeof(void()) is interpreted as a function type and it is ill-formed as for [5.3.3/1] (emphasis mine):

    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())) is an expression that has incomplete type void (note that sizeof is an unevaluated context) and it is ill-formed as for [5.3.3/1] (emphasis mine):

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

In both cases GCC compiles the code with a warning.