20

This question is inspired by Is sizeof(void()) a legal expression? but with an important difference as explained below.

The expression in question is:

sizeof( int() )

In the C++ grammar there appears:

unary-expression:

  • sizeof unary-expression
  • sizeof ( type-id )

however, ( int() ) can match both of these cases with different meanings:

  • As a unary-expression, it is a value-initialized int prvalue, surrounded in redundant parentheses
  • As a type-id, it is the type of a function with no parameters returning int.

In the semantic constraints for sizeof, i.e. C++14 [expr.sizeof]/1, it explains that the form sizeof( type-id ) may not be applied to a function type.

However I'm not sure whether the violation of that semantic constraint implies that sizeof( int() ) is correct and uses the sizeof unary-expression form; or whether there is some other rule that disambiguates the two cases at an earlier stage of grammar matching.

NB. For the other question sizeof(void()), neither interpretation is valid, so it could be argued that the compiler is correct to reject the expression with an error message indicating it matched the type-id form. However, gcc rejects sizeof( int() ) with a message about type-id.

To be clear, my question is: "Is sizeof( int() ) a legal expression?", particularly on the detail of how the grammar matching works when both of the above bulleted cases match.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • Of course whatever `sizeof(int())` is *intended* to mean, there's certainly a clearer way to say it -- most likely `sizeof (int)`. (Yes, it's a language-lawyer question, so that's not a problem, I just thought I'd mention it.) – Keith Thompson Sep 01 '16 at 22:36
  • @skypjack please read first paragraph of my question – M.M Sep 02 '16 at 11:05
  • I've read it as a whole. I agree that none of them should be closed. I'm voting to reopen also this one. – skypjack Sep 02 '16 at 12:16

1 Answers1

22

No, sizeof( int() ) is ill-formed because int() is taken to be a type-id. Specifically, it's a function type, and sizeof cannot be applied to a function type.

[dcl.ambig.res]/2:

An ambiguity can arise from the similarity between a function-style cast and a type-id. The resolution is that any construct that could possibly be a type-id in its syntactic context shall be considered a type-id.

with this exact example given:

void foo(signed char a) {
    sizeof(int());                // type-id (ill-formed)
    sizeof(int(a));               // expression
    sizeof(int(unsigned(a)));     // type-id (ill-formed)
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
T.C.
  • 133,968
  • 17
  • 288
  • 421
  • 3
    This is a good answer -- except for the minor detail that it doesn't actually answer the question. You might want to mention that no, `sizeof( int() )` is not legal (because `sizeof` cannot be applied to a function type). – Keith Thompson Sep 01 '16 at 21:41
  • It's an interesting question & answer. The type int() can't be used with sizeof even though it can readily be assigned to an int(*)() without a cast (which presumably can be used with sizeof). – Klitos Kyriacou Sep 01 '16 at 21:49
  • @KlitosKyriacou: `int(*)()` is a pointer type. Such an assignment is legal without a cast simply because an expression of function type is (in most contexts) implicitly converted to a pointer. – Keith Thompson Sep 01 '16 at 22:40