Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating a Class in C++: Strange Syntax Bug

I've never run into this before in C++ but it's odd that it still compiles but doesn't do what I expected. Can someone tell me what it does do? Please see the code, more info follows.

#include <iostream>
using namespace std;

class Test{
    public:
        Test();
};

Test::Test(){ cout << "ctor" << endl; }

int main(void){

    Test t();  // this compiles but doesn't call the constructor

    return(0);
}

It will compile, but if I try to use "t" it won't. I was only dependent on constructor functionality, and my code didn't work as expected. The solution is to lose the parenthesis "Test t();" to "Test t;". My question is what is going on in the "Test t();" example, and what does the compiler think is happening that it lets it compile.

like image 731
Kendrick Taylor Avatar asked Dec 18 '12 02:12

Kendrick Taylor


2 Answers

This is the Most Vexing Parse. Basically, according to the C++ parsing rules, what you have there isn't an object of type Test named t, but rather a function declaration for a function t which takes zero arguments and returns a Test.

Incidentally, clang++ actually recognizes this situation and emits a warning, telling you that this probably isn't doing what you want.

like image 101
Lily Ballard Avatar answered Nov 01 '22 22:11

Lily Ballard


This is a common problem that is aptly named as the most vexing parse. Your line Test t(); can be interpreted in one of two ways.

  1. It can declare a variable t which is of type Test
  2. It can declare a function t(), which returns a Test value and takes no arguments

The C++ standard unfortunately requires the compiler to consider the second alternative, which is quite a vexing parse.

The easiest way to fix that parse is to get rid of the parenthesis and simply declare your variable as such :

Test t; // Will call the default constructor
like image 29
Fred Avatar answered Nov 01 '22 22:11

Fred