logoalt Hacker News

pjmlpyesterday at 3:59 PM1 replyview on HN

While not automated, you can make use of function-try-blocks, e.g.:

    struct Example {
        Example() = default;

        ~Example()
        try {
        // elease resources for this instance
        } catch (...) {
            // take care of what went wrong in the whole destructor call chain
        }
    };
-- https://cpp.godbolt.org/z/55oMarbqY

Now with C++26 reflection, one could eventually generate such boilerplate.


Replies

layer8yesterday at 4:13 PM

What I’m thinking of is that the C++ exception runtime would attach exceptions from destructors to any in-flight exception, forming an exception tree, instead of calling std::terminate. (And also provide an API to access that tree.) C++ already has to handle a potentially unlimited amount of simultaneous in-flight exceptions (nested destructor calls), so from a resource perspective having such a tree isn’t a completely new quality. In case of resource exhaustion, the latest exception to be attached can be replaced by a statically allocated resources_exhausted exception. Callbacks like the old std::unexpected could be added to customize the behavior.

The mechanism in Java I was alluding to is really the Throwable::addSuppressed method; it isn’t tied to the use of a try-block. Since Java doesn’t have destructors, it’s just that the try-with-resources statement is the canonical example of taking advantage of that mechanism.

show 1 reply