Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass by value and different behavior

Tags:

c++

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

like image 575
FrozenHeart Avatar asked May 31 '13 15:05

FrozenHeart


People also ask

What is the difference between pass by value and pass by?

Use pass by value when when you are only "using" the parameter for some computation, not changing it for the client program. In pass by reference (also called pass by address), a copy of the address of the actual parameter is stored.

What is pass by value with example?

"Passing by value" means that you pass the actual value of the variable into the function. So, in your example, it would pass the value 9. "Passing by reference" means that you pass the variable itself into the function (not just the value). So, in your example, it would pass an integer object with the value of 9.

What is the difference between pass by value?

Passing by reference means the called functions' parameter will be the same as the callers' passed argument (not the value, but the identity - the variable itself). Pass by value means the called functions' parameter will be a copy of the callers' passed argument.

What does it mean to pass a value?

When you pass a value-type parameter to a function by value, it means that the changes you make to that parameter inside the function will only be affected while inside that function. There will be no effect on the original data that is stored in the argument value.


1 Answers

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;
}
like image 93
Andrei Avatar answered Oct 12 '22 05:10

Andrei