struct Foo {
int a_;
Foo(): a_(0) { cout << "Default Ctor : " << a_ << endl; }
Foo(int a): a_(a) { cout << "Ctor with parameters : " << a_ << endl; }
Foo(const Foo& foo): a_(foo.a_) { cout << "Copy Ctor : " << a_ << endl; }
~Foo() { cout << "Dtor : " << a_ << endl; }
};
Foo min(Foo f1, Foo f2) {
return f1.a_ < f2.a_ ? f1 : f2;
}
int main(){
Foo f1(1), f2(2), f3;
f3 = min(f1, f2);
return 0;
}
// Output :
// Ctor with parameters : 1
// Ctor with parameters : 2
// Default Ctor : 0
// Copy Ctor : 1
// Copy Ctor : 2
// Copy Ctor : 1
// Dtor : 1 <- confused about the order here, wondering why the order is not 2 -> 1 -> 1
// Dtor : 2
// Dtor : 1
// Dtor : 1
// Dtor : 2
// Dtor : 1
I am confused about why the return object from the min function is destructed before two local Foo objects. If the return object is destructed even before the min function ends, how can f3 be assigned?
In graphical way, those output lines are corresponding to creation and deletion o temporaries and local variables as shown below:
g++ prog.cc -Wall -Wextra
Ctor with parameters : 1 - Foo f1(1)
Ctor with parameters : 2 - Foo f2(2)
Default Ctor : 0 - Foo f3
Copy Ctor : 2 - min(Foo f1,
Copy Ctor : 1 - min( Foo f2)
Copy Ctor : 1 - return f1.a_ < f2.a_ ? f1 : f2;
Dtor : 1 - f1.a_ < f2.a_ ? f1 : f2;
Dtor : 1 - min(Foo f1,
Dtor : 2 - min( Foo f2)
Dtor : 1 - f3
Dtor : 2 - f2
Dtor : 1 - f1
Function arguments are local variables. As you defined them as values, they are getting initialized by copy constructor. They are getting destroyed on exit from function in example above (implementation defined).
Results of expressions are temporary objects. Ternary expression materializes only one of two.
Variations may happen due copy elision or due implementation, e.g. ternary may elide creation of temporary in this context or function could be inlined, which results in function parameters to be destroyed at different time. Hence in standards it's implementation-defined, whether it happens on exit from or on at the end of the enclosing full-expression.
Ctor with parameters : 1 - Foo f1(1)
Ctor with parameters : 2 - Foo f2(2)
Default Ctor : 0 - Foo f3
Copy Ctor : 2 - min(Foo f1,
Copy Ctor : 1 - min( Foo f2)
Copy Ctor : 1 - return f1.a_ < f2.a_ ? f1 : f2;
Dtor : 1 - min(Foo f1,
Dtor : 2 - min( Foo f2)
Dtor : 1 - min(f1, f2) (f1.a_ < f2.a_ ? f1 : f2)
Dtor : 1 - f3
Dtor : 2 - f2
Dtor : 1 - f1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With