17

This is a follow-up to my previous question What is the order of destruction of function arguments? because I accidentally confused arguments with parameters. Thanks to Columbo and T.C. for clearing me of terminology confusion in the comments of that question.

If the body of some function f with parameters p_1, ..., p_n of types T_1, ..., T_n respectively throws an exception, finishes or returns, in what order are the parameters destroyed and why? Please provide a reference to the standard, if possible.

Examples:

template <typename ... Args>
void f(Args ... params) {} // in what order are params destroyed?

void f(T1 p1, T2 p2, T3 p3) {} // in what order are p1, p2 and p3 destroyed?
Community
  • 1
  • 1
jotik
  • 17,044
  • 13
  • 58
  • 123

1 Answers1

14

The exact point in time at which parameters are destroyed is unspecified:

CWG decided to make it unspecified whether parameter objects are destroyed immediately following the call or at the end of the full-expression to which the call belongs.

The order in which parameters are constructed is unspecified as well, but because function parameters have block scope, although their order of construction is unspecified, destruction is in the reverse order of construction. E.g. consider

#include <iostream>

struct A {
    int i;
    A(int i) : i(i) {std::cout << i;}
    ~A() {std::cout << '~' << i;} 
};

void f(A, A) {}

int main() {
    (f(0, 1), std::cout << "#");
}

prints 10#~0~1 with GCC and 01#~1~0 with Clang; they construct parameters in different orders, but both destroy in the reverse order of construction, at the end of the full-expression the call occurs in (rather than right after returning to the caller). VC++ prints 10~0~1#.

Columbo
  • 60,038
  • 8
  • 155
  • 203
  • 2
    Is there any requirement that destruction order is the reverse of construction order? – M.M May 02 '16 at 22:29
  • @M.M I imagine even if there wasn't, it would be implicitly necessary since otherwise it could easily mess up stuff with RAII, like cause a deadlock with two locks being held and not released in the proper order. – user541686 May 02 '16 at 22:31
  • @M.M That probably is the case in practice. However, parameters do not have automatic storage duration and aren't temporaries, so I can't find any formal statement (and I don't see why it would be helpful). – Columbo May 02 '16 at 22:32
  • @M.M It makes sense that there should be since there might be dependencies between the objects, so they should be destroyed in the reverse order as they were allocated. – Nikos Kazazakis May 02 '16 at 22:32
  • 1
    "parameters do not have automatic storage duration" huh? – T.C. May 02 '16 at 22:40
  • 1
    @M.M Note that it is also possible to introduce dependencies between the parameters **after** their construction, during the execution of the body. Generally, this might not be sensible, but... maybe it turns out to be practical in some cases. – jotik May 02 '16 at 22:41
  • @T.C. AFAICS automatic storage duration is defined as what block scope variables can have, which parameters aren't. – Columbo May 02 '16 at 22:41
  • 3
    @Columbo Hmm...scope of function parameters are covered under [basic.scope.block] and other places of the standard clearly considers them automatic (e.g., [class.copy]/31-32). – T.C. May 02 '16 at 22:46
  • @T.C. Just another oddity I guess. Anyway, adjusted the answer. – Columbo May 02 '16 at 22:49
  • 3
    To make sure life is never dull, MSVC prints `10~0~1#` (the destructors are called from within `f`). – bogdan May 04 '16 at 22:12
  • Does this CWG resolution appear in any standard or draft? – M.M May 11 '16 at 07:32
  • @M.M The current status is "drafting", so appropriate wording is currently being drafted. – Columbo May 11 '16 at 10:17
  • @nikaza, if the order of construction or destruction is not defined, it is then impossible to set dependencies. – Jean-Baptiste Yunès May 13 '16 at 17:43
  • Update: the C++17 standard ended up making the point of destruction (return versus full-expression) *implementation-defined*, not *unspecified* – M.M Mar 17 '20 at 07:01
  • https://stackoverflow.com/questions/39824814/sequencing-of-function-parameter-destruction – M.M Mar 17 '20 at 07:13