0

I have a C++ class that defines a destructor, and I'm returning an object of this class by value from a function. However, I noticed that the destructor is not being called when the function returns. Instead, it's only being called when the object goes out of scope at the end of the main function. Additionally, I noticed that when I print the address of a variable in the object before and after the function call, the address remains the same.

Here's a simplified version of my code that demonstrates the issue:

#include <iostream>

class MyClass {
public:
    int i;
    
    MyClass() {
        std::cout << "Constructing MyClass object" << std::endl;
    }
    
    ~MyClass() {
        std::cout << "Destructing MyClass object" << std::endl;
    }
};

MyClass createObject() {
    MyClass obj;
    obj.i = 42;
    std::printf("Address of i inside createObject: %p\n", &obj.i);
    return obj;
}

int main() {
    MyClass newObj = createObject();
    std::printf("Address of i inside main: %p\n", &newObj.i);
    return 0;
}

When I run this program, the output is:

Constructing MyClass object
Address of i inside createObject: 0x7fff54c8a15c
Address of i inside main: 0x7fff54c8a15c
Destructing MyClass object

I was expecting the destructor to be called when createObject() returns, but that doesn't seem to be happening. Can anyone explain why this is the case, and how I can ensure that the destructor is called when returning an object by value from a function? Also, why does the address of the variable i in the object not change after being returned from the function?

Elhazin
  • 41
  • 2
  • 1
    There's no need for a destructor because you are returning `obj`. This is called return value optimization (RVO). There is only one `MyClass` object in your program, and that is correctly destroyed in `main`. This is also the reason that the address of `i` does not change. – john May 02 '23 at 18:18
  • 1
    This is NRVO. To suppress it, `return std::move(obj);`. – Artyer May 02 '23 at 18:18
  • 1
    Or consult your compiler documentation for an option that disables RVO. – user4581301 May 02 '23 at 18:19
  • 2
    See also [here](https://stackoverflow.com/q/12953127/631266) – Avi Berger May 02 '23 at 18:19
  • 1
    Side note: this is one of the rare cases where the optimizer is allowed to change the observable behaviour of a program. See [the As-if rule](https://en.cppreference.com/w/cpp/language/as_if) and [copy elision](https://en.cppreference.com/w/cpp/language/copy_elision) for more details. – user4581301 May 02 '23 at 18:21
  • You should print the value of `this` in your constructor and destructor, not just a simple string. This way, you will see which object was created and destroyed. – PaulMcKenzie May 02 '23 at 18:55

0 Answers0