Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When passing a class by-value, does the caller or callee call the destructor?

Suppose that I have the following (trimmed down) code:

class P { P(); P(const P&); ~P(); }

void foo(P x) {
  ...
}

void bar() {
  P p{};
  foo(p); // compiler uses P::(const P&) to construct the value for x
  ...
  // compiler calls P::~P() on p
}

The compiler must create a copy of p in order to call foo, so the caller invokes the copy constructor before the call. My question is, who is in charge of destroying this created object? There seem to be two valid choices:

  1. The callee (i.e. foo) calls the destructor on all of its by-value arguments before it returns and then the caller deallocates the memory (by popping it off the stack).
  2. The callee doesn't do anything, and the caller (i.e. bar) calls the destructor on all of the temporaries before the sequence point at the end of the foo(p) call.
like image 798
Gregory Avatar asked Jun 13 '19 15:06

Gregory


2 Answers

The standard answers this question in [expr.call]/4, with a surprising amount of elaboration:

... The initialization and destruction of each parameter occurs within the context of the calling function. [ Example: The access of the constructor, conversion functions or destructor is checked at the point of call in the calling function. If a constructor or destructor for a function parameter throws an exception, the search for a handler starts in the scope of the calling function; in particular, if the function called has a function-try-block (Clause 18) with a handler that could handle the exception, this handler is not considered. —end example ]

In other words, the destructor is invoked by the calling function.

like image 182
Brian Bi Avatar answered Nov 06 '22 04:11

Brian Bi


The caller destroys it. See https://en.cppreference.com/w/cpp/language/lifetime. Quoting:

All temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created, and if multiple temporary objects were created, they are destroyed in the order opposite to the order of creation.

Also keep this as general rule - one, who creates, destroys. Usually in reversed order.

like image 41
Radosław Cybulski Avatar answered Nov 06 '22 03:11

Radosław Cybulski