5

Does a call to a trivial destructor end the lifetime of an object? I read this and this but didn't find a good explanation. These threads state that a trivial destructor call has no effect and code like struct A { int x; } a; a.~A(); a.~A(); is legal. But I found that example in the standard:

struct C { };
void f() {
    C * pc = new C;
    using C2 = C;
    pc->C::~C2(); // OK, destroys *pc
    C().C::~C(); // undefined behavior: temporary of type C destroyed twice
    using T = int;
    0 .T::~T(); // OK, no effect
    0.T::~T(); // error: 0.T is a user-defined-floating-point-literal (5.13.8)
}

Here C has trivial destructor but still double destruction of an object of type C has undefined behavior?

Lassie
  • 853
  • 8
  • 18
  • You should never call destructors unless you've used placement new. – Ted Lyngmo Apr 06 '20 at 19:23
  • Good that you are asking. One of the valid effects of undefined behaviour is nothing happens, so you have to be wary. [Does this link clear anything up?](https://en.cppreference.com/w/cpp/language/lifetime) – user4581301 Apr 06 '20 at 19:29
  • "Parsing issue" for `0.T` even if you don't provide `operator ""T`. – Jarod42 Apr 06 '20 at 19:31
  • Rereading the question and re-reading the link, no the link won't help. – user4581301 Apr 06 '20 at 19:31
  • @user4581301 still does not answer my question. `However, if a program ends the lifetime of an non-trivial object explicitly, it must ensure that a new object of the same type is constructed in-place (e.g. via placement new) before the destructor may be called implicitly...` But what if the object is trivial? You say it's undefined, but I don't find anything on cppreference. – Lassie Apr 06 '20 at 19:33
  • @Lassie What I *thought* was going on was undefined. Now I sit back and wait for someone who groks the standard, same as you. – user4581301 Apr 06 '20 at 19:35
  • You may want to add `language-lawyer` tag, although it looks to me like walnut already addressed the crux of the question. – Eljay Apr 06 '20 at 19:51

1 Answers1

9

Starting with C++20 trivial destructor calls end the lifetime of objects. Before that they did not and it was valid to call the destructor multiple times.

In C++17 (draft N4659) trivial destructors are explicitly excluded from ending the lifetime in [basic.life]/1.3 and objects with trivial destructor would live instead until their storage duration ends or their storage is reused ([basic.life]/1.4).

This was changed with the resolution of CWG issue 2256 in this draft commit.

Also note that pseudo-destructor calls also end the lifetime in C++20, but did not before that. Both questions you link in your question are talking about such pseudo-destructor calls. See the compatibility note against C++17 in [diff.cpp17.basic]/1 of the draft (N4861).

walnut
  • 21,629
  • 4
  • 23
  • 59