views:

612

answers:

8

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? Thanks!

A: 

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
+12  A: 

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.

Charles Bailey
+4  A: 

Yet another most-vexing-parse hit. See for instance http://stackoverflow.com/questions/1300327/sort-function-does-not-work-with-function-object-created-on-stack

AProgrammer
+2  A: 

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
+7  A: 

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

Liz Albin
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.
Steve314
+6  A: 

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;
Peter Alexander
+1  A: 
MyClass myObj();

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

sbk
+6  A: 

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