Why does C++ allow us to surround the variable name in parentheses when declaring a variable?

C++Most Vexing-Parse

C++ Problem Overview


For example a declaration such as that:

int (x) = 0;

Or even that:

int (((x))) = 0;

I stumbled upon this because in my code I happened to have a fragment similar to the following one:

struct B
{
};

struct C
{
  C (B *) {}
  void f () {};
};

int main()
{
  B *y;
  C (y);
}

Obviously I wanted to construct object C which then would do something useful in its destructor. However as it happens compiler treats C (y); as a declaration of variable y with type C and thus it prints an error about y redefinition. Interesting thing is that if I write it as C (y).f () or as something like C (static_cast<B*> (y)) it will compile as intended. The best modern workaround is to use {} in constructor call, of course.

So as I figured out after that, it's possible to declare variables like int (x) = 0; or even int (((x))) = 0; but I've never seen anyone actually using declarations like this. So I'm interested -what's the purpose of such possibility because for now I see that it only creates the case similar to the notorious "most vexing parse" and doesn't add anything useful?

C++ Solutions


Solution 1 - C++

Grouping.

As a particular example, consider that you can declare a variable of function type such as

int f(int);

Now, how would you declare a pointer to such a thing?

int *f(int);

Nope, doesn't work! This is interpreted as a function returning int*. You need to add in the parentheses to make it parse the right way:

int (*f)(int);

The same deal with arrays:

int *x[5];   // array of five int*
int (*x)[5]; // pointer to array of five int

Solution 2 - C++

There's generally allowed to use parentheses in such declarations because the declaration, from the syntactical point of view looks always like this:

<front type> <specification>;

For example, in the following declaration:

int* p[2];

The "front type" is int (not int*) and the "specification" is * p[2].

The rule is that you can use any number of parentheses as needed in the "specification" part because they are sometimes inevitable to disambiguate. For example:

int* p[2]; // array of 2 pointers to int; same as int (*p[2]);
int (*p)[2]; // pointer to an array of 2 ints

The pointer to an array is a rare case, however the same situation you have with a pointer to function:

int (*func(int)); // declares a function returning int*
int (*func)(int); // declares a pointer to function returning int

This is the direct answer to your question. If your question is about the statement like C(y), then:

  • Put parentheses around the whole expression - (C(y)) and you'll get what you wanted
  • This statement does nothing but creating a temporary object, which ceases to living after this instruction ends (I hope this is what you intended to do).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPredelnikView Question on Stackoverflow
Solution 1 - C++user1084944View Answer on Stackoverflow
Solution 2 - C++EthourisView Answer on Stackoverflow