2

Suppose I have the following structure:

struct A {
    A() { cout << "Default ctor\n"; }

    A(int) { cout << "Ctor with params\n"; }
};

And then I want to create an object. In Java I've got accustomed to use brackets when I create an object, so the first desire is to write something like that:

A a();

The code compiles, but a actually isn't an instance of A, it is something different.

So the question is: what is a and why should I omit the brackets to call the default constructor?

Alexey
  • 1,198
  • 1
  • 15
  • 35

2 Answers2

3

See the most vexing parse, what you are actually doing is declaring a function. The way to alleviate this problem is to either eliminate the () or to use the C++11 uniform initialization syntax,

A a;
A a{};
Curious
  • 20,870
  • 8
  • 61
  • 146
  • This is **not** the "most vexing parse"; look at the examples on the page you linked to. It is simply a function declaration. The most vexing parse is far more subtle, which is why it's vexing. – Pete Becker Jun 26 '17 at 15:14
  • @PeteBecker clang seems to think it is the most vexing parse (although gcc does not), see https://wandbox.org/permlink/jLNCBAxm6txCyeAf. And I do too, the first example in the wikipedia page was just another complicated version of the same, the most vexing parse originates from the fact that expressions like this are required by the C++ standard to be treated as function declarations, whereas the programmer might have meant it to be a variable declaration and initialization. And in such a situation, the compiler should warn you that you might have gotten it wrong. Therefore the vex. – Curious Jun 26 '17 at 15:21
  • "The first example was just another complicated version..." -- exactly. You won't find **this simple code** on that page, because it's **not** the most vexing parse. The most vexing parse is far more subtle. Granted, the term is in serious danger of becoming a catchall that means "it's something I don't understand, so I'm vexed", but that's not its original meaning, nor is it the meaning given on that page. – Pete Becker Jun 26 '17 at 15:25
  • @PeteBecker maybe you are right, but I feel like the thing conveyed by the wikipedia page and this is that the most vexing parse is a situation where the compiler is open to interpret a statement as either a variable declaration and initialization or a function declaration. And this is the same situation (as warned by clang), so its not really an umbrella catchall that means "it's something I don't understand, so I'm vexed", it's just used to describe few more situations than was originally correct. But in doing so there still isn't any increase in general ambiguity. – Curious Jun 26 '17 at 15:42
2

In C++, A a(); is a forward declaration for a function called a that takes no arguments, and returns an A. It does not create an instance of A using the default constructor.

In Java, there is no need for forward declarations of functions, so A a(); can be read to be equivalent to A a;

This curiousity of C++ even has a name: see https://en.wikipedia.org/wiki/Most_vexing_parse

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • This is **not** the "most vexing parse". The page you link to shows examples of the most vexing parse, and this one is not there. – Pete Becker Jun 26 '17 at 15:16