FrozenHeart
FrozenHeart

Reputation: 20746

Pass by value and different behavior

Why does the following code gives a different output when compiling with gcc 4.7.2 and MSVC-11.0?

#include <iostream>

class Base
{
public:
    Base()
    {
        std::cout << "Base::Base() \n";
    }

    ~Base()
    {
        std::cout << "Base::~Base() \n";
    }
};

class Derived : public Base
{
public:
    Derived()
    {
        std::cout << "Derived::Derived() \n";
    }

    ~Derived()
    {
        std::cout << "Derived::~Derived() \n";
    }
};

void foo(Base) {}

int main()
{
    Derived instance;
    foo(instance);
}

gcc 4.7.2

Base::Base()

Derived::Derived()

Base::~Base()

Derived::~Derived()

Base::~Base()

MSVC-11.0

Base::Base()

Derived::Derived()

Base::~Base()

Base::~Base()

Why MSVC-11.0 doesn't print second Derived::~Derived()?

https://ideone.com/NF9FQf

Upvotes: 8

Views: 223

Answers (1)

Andrei
Andrei

Reputation: 5005

I am using MS Visual Studio 11.0.60315.01, cl version 17.0.60315.1.

Using this as main

int _tmain()
{
    Derived instance;
    foo(instance);

    return 0;
}

and putting a breakpoint on the return 0 line i get this output:

Base::Base()
Derived::Derived()
Base::~Base()
Base::~Base()

which is the one reported in the question.

Stepping out of main and into the crt results in this output:

Base::Base()
Derived::Derived()
Base::~Base()
Base::~Base()
Derived::~Derived()
Base::~Base()

Adding this to the Base class:

Base( const Base& b )
{
    std::cout << "Base::Base( const Base& b ) \n";
}

results in this output at return 0;

Base::Base()
Derived::Derived()
Base::Base( const Base& b )
Base::~Base()

and this output after all the destructors are executed:

Base::Base()
Derived::Derived()
Base::Base( const Base& b )
Base::~Base()
Derived::~Derived()
Base::~Base()

Adding a virtual destructor results in no changes (as expected):

Base::Base()
Derived::Derived()
Base::Base( const Base& b )
Base::~Base()
Derived::~Derived()
Base::~Base()

My guess would be that the output of MSVC is recorded incorrectly by the poster.

EDIT:

The full output (without the copy constructor) contains 3 Base destructors. Adding the copy constructor reduces that to 2 Base destructors.

The behaviour, without the copy constructor is equivalent to the output of:

void foo(Base) {}

int _tmain()
{
    {
        Derived instance;
        Base b(instance);
        foo(b);
    }

    return 0;
}

Upvotes: 1

Related Questions