3 ms·
I see a lot of people in this thread dumping on this idea, but in my opinion as someone who has built several large systems in C++, this pattern is not just goo
by kentonv 9y ago
I see a lot of people in this thread dumping on this idea, but in my opinion as someone who has built several large systems in C++, this pattern is not just good, it's essential. KJ (the C++ framework library built with Cap'n Proto that I use in all my projects now) has had KJ_DEFER() since just about the beginning, working basically exactly as described here, and I use it constantly.
If you write C++ with exceptions, you need this. If you simply place tear-down code at the end of the function instead, you are creating exception-unsafe code. Of course, ideally state is encapsulated in classes with destructors and tear-down happens there, but writing a whole class can often be overkill for a one-off use case. If you don't have a defer macro, you're going to get lazy and introduce bugs.
If you don't use exceptions, then you still need this, because your code almost certainly has lots of "if (error) return nullptr;" or whatever. Without `defer`, you need to stick the teardown code before every one of those returns, or you need to resort to "goto fail" error handling.
- quietbritishjim 9y ago> If you simply place tear-down code at the end of the function No one is suggesting this. They are saying that you use an RAII class such that it doesn't need tear down. In the example in the article, if std::ofstream calls close() in its destructor (which it does) then you don't need to DEFER a call to it. If you lock a mutex, use a RAII locker class so that you don't need to DEFER a call to unlock(). As someone once said of C++: "my favorite feature is the close brace", because it calls destructors for all objects on the stack, even during exception unwinding. Of course, the article is just using RAII. But I disagree with the style; rather than re-writing a DEFER(myfile.close()) in every single function that uses a file object, you should make the file class have an appropriate destructor, or at least write a wrapper that does. That way you re-use that code rather than having to re-write it over and over. > If you write C++ with exceptions, you need this. You absolutely do not. You need to use the core language feature that it is using: deterministically-called destructors.
- kentonv 9y ago> No one is suggesting this. At least one person in this thread is, in fact, suggesting this: https://news.ycombinator.com/item?id=15524405 https://news.ycombinator.com/item?id=15524405 > They are saying that you use an RAII class such that it doesn't need tear down. Yes, as I said in my original comment: "Of course, ideally state is encapsulated in classes with destructors and tear-down happens there, but writing a whole class can often be overkill for a one-off use case. If you don't have a defer macro, you're going to get lazy and introduce bugs." I do know how destructors work, thanks.
- quietbritishjim 9y agoI guess I took your comment the wrong way. Sorry about that.