https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118641
            Bug ID: 118641
           Summary: destruction order not respected
           Product: gcc
           Version: 14.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ing.russomauro at gmail dot com
  Target Milestone: ---

This web page:

https://cppquiz.org/quiz/question/323?result=OK&answer=bcad&did_answer=Answer

shows an error of gcc about destruction order in case of exception while
destructing local objects after having constructed the returned object.

It seems no one reported yet to gcc.


The code recalls an example from the standard, in [except.ctor]-p2.

I have elaborated a bit more with some std::cout and some few additional stuff,
here: https://godbolt.org/z/a454Ge5oY



Original code is:

struct A { };

struct Y { ~Y() noexcept(false) { throw 0; } };

A f() {
  try {
    A a;
    Y y;
    A b;
    return {};      // #1
  } catch (...) {
  }
  return {};        // #2
}

and the problem is that after the exception throw by y-destruction, the code
destroys object a before returned object constructed in #1 (that C++17
guarantees to be directly built on the caller space, since a prvalue is
there... but that's another theoretical story).

Please, check whether the standard contradicts itself about some allowed
optimization stated somewhere else.



My code elaboration is:

#include <iostream>
#include <stdexcept>

unsigned d = 0;
struct A {
    A(char c) : c_(c), p(new int()) {std::cout << "constr. " << c_ << '\n';}
    ~A() { std::cout << "destr. " << c_ << '\n'; delete p;}
    char c_;
    int *p;
};

struct Y { ~Y() noexcept(false) { throw std::runtime_error(""); } };

A f() {
    try {
        A a('a');
        Y y;
        A b('b');
        return {'c'};
    } catch (...) {
    }
    return {'d'};
}

int main()
{
    A x = f();
}

Reply via email to