4 ms·
What if you forget to call “defer”? Then your code is incorrect. That’s kludgy in comparison to RAII where it’s impossible to forget to call a destructor.
by CyberRabbi 6y ago
What if you forget to call “defer”? Then your code is incorrect. That’s kludgy in comparison to RAII where it’s impossible to forget to call a destructor.
- coldtea 6y agoThe whole point is that it's much easier to NOT forget defer (which goes right after the resource acquisition line), than to forget to free the resource (which happens much further down the function). So it's immediately better compared to the current C situation. As for compared to RAII? Well, thats one failure mode for defer (forgetting it), whereas there are dozens of ways to mess RAII...
- CyberRabbi 6y agoI made no comparison between “defer” and the current C situation. In comparison to RAII, “defer” as a language feature is a kludge. Mainly because RAII completely solves the problem of correct resource cleanup for API users while “defer” does not.
- coldtea 6y agoRAII is an idiom, not a language feature. Destructors might be the language feature, but they have their own issues and caveats. So I don't see the comparison...
- isogon 6y agoI think it's quite reasonable to compare defer and destructors, in that case. Destructors probably cannot be usefully imported into C while preserving the simplicity of the language: then you'll want at least unique_ptr to manage your memory with destructors, then probably shared_ptr, and some ownership semantics as you pass those around, et cetera. In that sense, defer strikes a balance between simplicity and usefulness. However, there is still a comparison.
- fnord123 6y agoRAII is a delight when it comes to local heap memory. However, if you want to pair fclose with a fopen call then you need to wrap fopen in a type and make the destructor call fclose. This is totally fine and I like it a lot in C++ and Rust, but it doesn't gel with existing C apis. Therefore I think defer is a good choice for C regardless of what I might choose were I to be implementing a language from scratch.
- ziml77 6y agoNon-obvious need to call defer was what made me stop trying out Go. When I was making HTTP requests there was no Close() method on the response so it seemed like it wasn't needed. But later I found out that there is a Close() method on the response's Body member that needs to be called (only one code sample in the docs even showed that). RAII is the best for ensuring that things get cleaned up even if it does lead to more boilerplate to add the pattern to things. But even .NET's IDisposable feels better than defer. It's established practice to implement it if your class contains something that must be disposed. And it's easy for tools to check if you haven't disposed of something that implements IDisposable. All that said, I find defer to be better than nothing. In C, the best I can do for cleanup is having all the cleanup functions called at the end with labels at the various points I need to jump to.