I'm perfectly able to do that, I just don't want it, because the result is terrible. The syntax no longer shows what happens when and where.
And, if you look at n3434 <https://www.open-std.org/JTC1/SC22/WG14/www/docs/n3434.htm>, you can see the following gem:
> the deferred block may itself contain other defer blocks, that are then executed in chain according to the same rules
This is the worst possible outcome. It means that a continuation passing style sub-language gets embedded in C.
{
defer { a(); defer { b(); }; c(); };
defer { d(); };
}
At the final closing brace shown, d() will be invoked first, then a(), then c(), then finally b(). Syntactically, the invocations appear in a-b-c-d order in the source code, but the actual execution is neither that nor the inverse d-c-b-a nor the single-level inverse order d-a-b-c.THAT is an unreadable mess. Good luck debugging that. Not dissimilar to chaining futures in modern async C++ (lambdas deeply nested in lambdas). Which is an abomination.
Your source code syntax is now completely detached from the execution order within a single thread.
Good luck getting that past code review.
Your reference to "no take only throw" makes no sense to me. The gist of that meme is "various characters making contradictory demands". Nobody is making demands here. There's no need for an "explicit alternative". Just don't defer at all, regardless of style. Write the error path / exit path explicitly, using gotos or the arrow pattern.