← Back to context

Comment by o11c

6 days ago

Notably, C++ and similar languages don't support lexical `finally` at all, instead relying on destructors, which are a function and obviously cannot affect the control flow of their caller ...

except by throwing exceptions, which is a different problem that there's no "good" solution to (during unwinding, that is).

I thought destructors were all noexcept now... or at the very least if you didn't noexcept, and then threw something, it just killed the process.

Although, strictly speaking, they could have each exception also hold a reference to the prior exception that caused the excepting object to be destroyed. This forms an intrusive linked list of exceptions. Problem is, in C++ you can throw any value, so there isn't exactly any standard way for you to get the precursor exception, or any standard way for the language to tell the exception what its precursor was. In Python they could just add a field to the BaseException class that all throwables have to inherit from.

  • > I thought destructors were all noexcept now...

    Destructors are noexcept by default, but that can be overridden with noexcept(false).

    > or at the very least if you didn't noexcept, and then threw something, it just killed the process.

    IIRC throwing out of a destructor that's marked noexcept(false) terminates the process only if you're already unwinding from something else. Otherwise the exception should be thrown "normally".