55

I was compiling a C++ program in Cygwin using g++ and I had a class whose constructor had no arguments. I had the lines:

MyClass myObj();
myObj.function1();

And when trying to compile it, I got the message:

error: request for member 'function1' in 'myObj', which is of non-class type 'MyClass ()()'

After a little research, I found that the fix was to change that first line to

MyClass myObj;

I could swear I've done empty constructor declarations with parentheses in C++ before. Is this probably a limitation of the compiler I'm using or does the language standard really say don't use parentheses for a constructor without arguments?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mring
  • 1,717
  • 2
  • 13
  • 28
  • @einpoklum regarding your edit, most people aren't going to find this because `vexing` is in the title. It really only help moderators to be able to find it better, maybe. I was able to find this because I googled *error declaring variable with empty parentheses c++*. Would you mind if we put the title back the way it was? – NathanOliver Apr 01 '21 at 14:32
  • @NathanOliver: My edit is for helping moderators correctly decide which is the best bug to mark as a dupe of - since that's not an obvious choice. But if you want a longer version which has both the phrase "most vexing parse" and more of the original, go ahead. – einpoklum Apr 01 '21 at 15:27

7 Answers7

63

Although MyClass myObj(); could be parsed as an object definition with an empty initializer or a function declaration the language standard specifies that the ambiguity is always resolved in favour of the function declaration. An empty parentheses initializer is allowed in other contexts e.g. in a new expression or constructing a value-initialized temporary.

MSalters
  • 173,980
  • 10
  • 155
  • 350
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
58

This is called the Most Vexing Parse issue. When the parser sees

MyClass myObj();

It thinks you are declaring a function called myObj that has no parameters and returns a MyClass.

To get around it, use:

MyClass myObj;
einpoklum
  • 118,144
  • 57
  • 340
  • 684
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • Hi, apart from being allocated on stack and heap respectively, is there any difference between `MyClass obj` and `MyClass *obj = new MyClass()`? – SexyBeast Jan 11 '15 at 19:38
  • 1
    A few. The first declares `obj` as an object of type `MyClass`, and will automatically be freed when scope exits. The second declares `obj` as an object of type `MyClass*`, which must be manually freed, and will be available after the scope exits. – Peter Alexander Jan 12 '15 at 20:39
  • Yeah yeah, that's precisely the result of getting allocated on the stack and heap respectively, right? – SexyBeast Jan 12 '15 at 21:26
  • @PeterAlexander: it is OK when a custom *non-default* ctor is used istead such as: `MyClass myObj(int i);`. Is there any different? – Steven Lee Jun 06 '21 at 07:32
20

I found this in the C++ standard (§8.5.8):

An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.

[Note: since () is not permitted by the syntax for initializer,

X a ();

is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X. The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). —end note ]

suszterpatt
  • 8,187
  • 39
  • 60
11

This is a fairly well-known issue and isn't compiler dependent. Essentially, you were declaring a function returning type MyObj. Not surprisingly, you couldn't call its constructor. See the C++ faq lite for a good explanation.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Liz Albin
  • 1,479
  • 8
  • 8
  • To expand - it's only an issue in certain contexts. Write "throw myexceptionclass ();", for example, and there's no confusion. The language is ambiguous in Petes context, but disambiguating rules (the reason the language strictly isn't really ambiguous) pick one interpretation. Of course the disambiguating rules mean the language isn't really ambiguous - but parsing experts say it anyway, so I'm allowed too! The most common disambiguating rules in a lot of languages are for operator precedence and associativity - C and C++ are much more ambiguous, and there are some odd issues as a result. –  Feb 23 '10 at 14:22
4
MyClass myObj();

That's parsed as a function declaration. The function is called myObj, takes no arguments and returns a MyClass object. I've never seen a compiler accepting that. On the other hand, MyClass* myPtr = new MyClass(); is acceptable, and may be that got you confused?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sbk
  • 9,212
  • 4
  • 32
  • 40
3

Your line makes the compiler think you are declaring a function named myObj which takes no arguments and returns a MyClass. This ambiguity resolution is indeed annoying.

Ari
  • 3,460
  • 3
  • 24
  • 31
1

The standard does not require parentheses.

int* x = new int;

is legal syntax.

In your case myclass myobj(); is a function prototype. Whereas myclass myobj; is a variable.

JonH
  • 32,732
  • 12
  • 87
  • 145