> The annoyance to me is that like all scope / defer constructs it gets wonky when paths split between a success and a failure path, and you do want the resource to escape in the former case. That's an area where RAII really shines.
Is this even supported by the proposal in question though? I don't see anything here that indicates any sort of escape analysis or object tracking is performed—resources are always cleaned up lexically so `using foo = handle(); return foo` will always call foo to be cleaned up, just like the equivalent `finally` statement.
That's correct, there is no escape analysis or anything like it. Though there is a way to handle the "I want to return a resource" case: the DisposableStack class. You can call `stack.move()` to "move" ownership of a resource (and rely on the place you're passing it to to do cleanup). E.g.
using stack = new DisposableStack();
stack.use(resource());
if (condition) {
// the resources will _not_ get disposed automatically by this return
// it's the caller's responsibility to call `stack.dispose()`
return stack.move();
}
> Is this even supported by the proposal in question though?
No and that’s exactly the problem.
If you “using” a resource and you leak it, you’ve now handed off a disposed off and probably useless resource.
If you don’t, and don’t, you have a resource leak.
In trivial cases this is fine-ish, just do whichever is needed, but when there are conditional paths internally (sometimes you signal an error others you return normally) you can’t “using” at all, you’re back to try/except and disposing by hand.
RAII does not have that issue, it does the right thing every time.
A few languages solve this by having additional constructs for these specific scenario (e.g. errdefer), though that requires more direct integration with the language’s error reporting, and thus forbids (or at least does not work with) alternate ones.
Is this even supported by the proposal in question though? I don't see anything here that indicates any sort of escape analysis or object tracking is performed—resources are always cleaned up lexically so `using foo = handle(); return foo` will always call foo to be cleaned up, just like the equivalent `finally` statement.