-1

What is the difference between the following three pieces of code with respect to MSVC?

Code 1: Foo ctor defined as:

Foo::Foo(Bar &bar = Bar());

Foo ctor used as:

Foo foo = new Foo();

Code 2: Foo ctor defined as:

Foo::Foo()
{
    Bar bar = Bar();
    Foo(bar);
}

Foo::Foo(Bar &bar);

Foo ctor used as:

Foo foo = new foo();

Code 3: Foo ctor defined as:

Foo::Foo(Bar &bar);

Foo ctor used as:

Bar bar = Bar();
Foo foo = new foo(bar);

Edit: Made corrections to the code. The intention was to explain the idea, didn't focus on the code, so made the mistake. Sorry about that.

The question specifically is to figure out the difference between code 2 and 3. Due to some reason, in the case of Code 2, the consumer of the Foo class ctor results in a crash and in case of Code 3 it doesn't. I don't have the specific code of the consumer, so cannot figure it out myself.

Waqar
  • 8,558
  • 4
  • 35
  • 43
Bonton255
  • 2,231
  • 3
  • 28
  • 44
  • `Foo foo();` is a function declaration. – jrok Mar 09 '14 at 08:24
  • 2
    Additionaly to what juanchopanza said, `Foo::Foo(Bar &bar = Bar());` is illegal because it attempts to initialize a reference to non-const with a temporary. That's an extension of MVSC, but not legal C++. – jrok Mar 09 '14 at 08:39
  • FYI the syntax to construct an object with no arguments is `Foo foo;` and the syntax for a delegating constructor is `Foo::Foo() : Foo(bar)` – M.M Mar 09 '14 at 08:45
  • Also see this: http://stackoverflow.com/questions/4989483/where-to-put-default-parameter-value-in-c – juanchopanza Mar 09 '14 at 08:46
  • @jrok - Yes you are right. GCC will not compile this saying "lvalue non-const reference cannot bind to incompatible temporary". I have been through that :) But MSVC compiles this - the question already mentions this is specific to MSVC – Bonton255 Mar 09 '14 at 09:10

1 Answers1

3

In the first two, you are not even calling a constructor, you are declaring a function:

Foo foo(); // function foo, returns a Foo object

To default construct a Foo, you need

Foo foo;   // C++11 and C++03
Foo foo{}; // C++11

Most of your code is either illegal, or it doesn't do what you expect. For example, this constructor doesn't do anything other than create a local Bar variable bar, and an attempt to create an instance type Foo with the same name:

Foo::Foo()
{
    Bar bar = Bar(); // local variable bar
    Foo(bar);        // error: 'bar' has a previous declaration as 'Bar bar'
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • "anonymous one of type Foo" Nope :) It's a default constructed `Foo` named `bar`. – jrok Mar 09 '14 at 08:27
  • @jrok Hmm. `Foo` has a converting constructor from `Bar`, and `bar` is already a `Bar` instance. Did I miss something? – juanchopanza Mar 09 '14 at 08:29
  • 1
    @jrok Ah yes, you're absolutely right. So the error is that there is already something called `bar`. I will blame the lack of coffee. – juanchopanza Mar 09 '14 at 08:32