55

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?

BЈовић
  • 62,405
  • 41
  • 173
  • 273
skypjack
  • 49,335
  • 19
  • 95
  • 187

6 Answers6

58

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

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 4
    Isn't it interpreted as in `decltype(void())` (note that it is not a function type in this case)? I would have said it indeed. Why do they differ? – skypjack Sep 01 '16 at 18:22
  • 5
    @skypjack When you use a function type with `decltype` it gives the type of the return-type. In the case of `void()` the return type is `void` so that's the type of `decltype(void())`. – Some programmer dude Sep 01 '16 at 18:27
  • 6
    So why `decltype(void(void))` doesn't work, as well as `decltype(int(int))`? No, it is not a function type when using`decltype`. In the case of `sizeof` I cannot say. – skypjack Sep 01 '16 at 18:32
  • 3
    @skypjack I think I figured it out now, `decltype` needs an *expression*, and not a type. `void()` is not actually a type here, but an expression, a C-style cast (just like e.g. `int(12.34)`) `void(void)` is not an expression therefore it doesn't work. How the compiler parses different things depends on the context, when it expects a type it parses as a type, when it expects an expression it parses as an expression. `sizeof()` (with the parentheses) expects first of all a type, otherwise it's parsed as a parenthesized expression. – Some programmer dude Sep 01 '16 at 18:43
  • 4
    [cppreference sizeof](http://en.cppreference.com/w/cpp/language/sizeof) provides an example usage of `sizeof` opeartor, and it clearly says **size of function** to `sizeof(void())`, and says, it's an error, here, `// cout << "size of function: " << sizeof(void()) << '\n'; // error`, i think it's really a function type. – Ahmad Khan Sep 01 '16 at 18:49
  • 2
    @JoachimPileborg I would create a question for this and accept this exact answer, so as to let it for future readers. What do you think? It's an interesting answer in the answer indeed. – skypjack Sep 01 '16 at 18:50
  • 1
    @skypjack You can always copy my comment into an answer for such a question if you'd like. (As long as you give me some credit... ;) ) – Some programmer dude Sep 01 '16 at 18:55
  • 1
    @JoachimPileborg [That's it](http://stackoverflow.com/questions/39279074/what-does-the-void-in-decltypevoid-means-exactly/39279075#39279075). No reputation or credits wanted, just an interesting answer in the answer that is worth to be discussed apart. Let's see what the language-lawyers will say about that. – skypjack Sep 01 '16 at 19:04
  • 1
    @JoachimPileborg: *"When you use a function type with `decltype` it gives the type of the return-type."*... I'm not convinced. Are you saying the argument which is passed to `decltype` is a *type*, not a *value*? – Nawaz Sep 01 '16 at 19:05
  • @JoachimPileborg So, `sizeof((void()))` considers `void()` the same way `decltype` does, right? – skypjack Sep 01 '16 at 20:19
  • 1
    @skypjack Yes, `(void())` is an expression. – Some programmer dude Sep 02 '16 at 05:29
39

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
Khalil Khalaf
  • 9,259
  • 11
  • 62
  • 104
8

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
Arnav Borborah
  • 11,357
  • 8
  • 43
  • 88
6

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.

skypjack
  • 49,335
  • 19
  • 95
  • 187
1

As already highlighted in the docs here http://en.cppreference.com/w/cpp/language/sizeof

Notes

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

Since void() is a function type, so its not a valid type of sizeof()

Note:

void() is a function that takes no arguments and returns nothing

Quoting a Example from Docs:

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

So Answers to your questions:

1)No it is not a legal Expression.

2)It will show as 1 , but will show a warning

3)same as 1).

JAAD
  • 12,349
  • 7
  • 36
  • 57
1

Straigth from the C99 reference NO

Stated in the document under section 6.5.3.4 The sizeof operator:

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.

According to item 19 and 20 of section 6.2.5 Types:

  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’’.

Thus void() is a function type derived from an incomplete type and its illegal as operand for the sizeof. That said its returns will depends on the compiler implementation and does not have any return value guaranteed

C99 Standard

WelsonJR
  • 299
  • 3
  • 5
  • 1
    See the tags of the question. – skypjack Sep 11 '16 at 10:14
  • 1
    Thanks for your feedback, however there is no difference in the definition of void type in the section 3.9.1 item 9 of current C++ standard and regarding the sizeof operator in section 5.3.3 item 1: The sizeof operator shall not be applied to an expression that has function or incomplete type... [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf] – WelsonJR Sep 11 '16 at 10:32
  • 2
    Absolutely, but for the question is tagged C++, it's worth mentioning the right reference. That's all. – skypjack Sep 11 '16 at 10:33