19

Consider the following code:

int main() {
    int(s);
}

I am surprised by the fact that it creates valid variable s. Can anyone explain what's happening here?

bezet
  • 810
  • 7
  • 13
  • 1
    Same reason why both `return(0);` and `return 0;` work. – Henri Menke Aug 31 '17 at 22:53
  • 3
    Some complicated type definitions are *required* to use parentheses to declare, so that the relevant modifiers are grouped properly. Redundant parentheses are generally ignored. – Mark Ransom Aug 31 '17 at 22:53
  • It works with non-primitives too. – bezet Aug 31 '17 at 22:53
  • I think you need a better example or a link back to [the question that spawned this question](https://stackoverflow.com/questions/45990714/how-to-print-the-values-of-two-dimensional-pair-vector) to get the answer we are both really interested in. – user4581301 Aug 31 '17 at 22:57
  • @HenriMenke actually it is not the same reason. `0` is an expression but `s` in OP's code is a declarator – M.M Sep 01 '17 at 00:12
  • @HenriMenke: `return` takes an expression, and `(expression)` is also an expression. But `int (s)` is a definition, not an expression. I.e. _not_ the same reason. Cf. `return 0+0` works but `int s+0` does not. – MSalters Sep 01 '17 at 08:39

2 Answers2

26

[dcl.meaning] in the Standard says:

In a declaration T D where D has the form ( D1 ) the type of the contained declarator-id is the same as that of the contained declarator-id in the declaration T D1.

Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex declarators.

More simply, you can put parentheses around anything considered a "declarator" in the C++ grammar. (Loosely speaking, a declarator is a part of a declaration without the initial specifiers and types which contains one name.)

In your example, the identifier s is a declarator, so you're allowed to put parentheses around it and the meaning doesn't change.

The reason for this, as the second quoted sentence hints, is that it can be necessary when things get more complicated. One example:

int * a [10];     // a is an array of ten pointers to int.
int ( * b ) [10]; // b is a pointer to an array of ten ints.
Community
  • 1
  • 1
aschepler
  • 70,891
  • 9
  • 107
  • 161
3

Just to add to the other answers; in the grammar summary for declarators (C++14 [dcl.decl]/4) you can find:

ptr-declarator:
    noptr-declarator

noptr-declarator:
    ( ptr-declarator )

(I have omitted other details of the grammar). You can see from this that any declarator may be parenthesized and it would still match the same grammar rule.

M.M
  • 138,810
  • 21
  • 208
  • 365