3 ms·
The benefit of RAII is that a return value can guarantee cleanup isn't forgotten about. You can't do that with defer. If I return an FD and I need you to close
by kllrnohj 4y ago
The benefit of RAII is that a return value can guarantee cleanup isn't forgotten about. You can't do that with defer. If I return an FD and I need you to close it, I can just enforce that trivially by returning an RAII type. The same thing in a defer language requires both reading function documentation and not forgetting the defer.
Meanwhile, defer-like utility can trivially be created in top of RAII. So RAII is the more versatile and useful building block
- klodolph 4y agoI'm aware of the benefits of RAII. Those static analysis tools are really, really easy to use. For example, if I forget to invoke cancel() in context.WithCancel() in Go, it gets caught automatically. Something defer-like is annoying to create on top of RAII (or at least annoying in C++). What you put in defer can be a whole function, with access to the enclosing scope, and (critically) the return values in Go, and can know whether the program is panicking (equivalent to throwing an exception). In C++, variables in the enclosing scope are being destroyed, and since any defer implementation would be in a destructor, you can't throw an exception from the destructor. In Go, you can propagate errors from the code called by defer (use the deferred code to return an error result from the enclosing function), or panic() inside defer, and it's a normal error or normal panic. It's not something you could reimplement easily with destructors in C++. 99% of the time you're not using these fancy features. That's fine. 99% of the time, your RAII is just destroying an object at the end of scope.