4 ms·
I was referring to the things from the video, where RAII and generic types are emulated with complex macros. And where std::string(_view) is re-invented
by varajelle 5y ago
I was referring to the things from the video, where RAII and generic types are emulated with complex macros.
And where std::string(_view) is re-invented
- flohofwoe 5y agoFair point, but cleanup and string handling are hardly problems where C++ has a monopoly, or even particularly good solutions to offer ;)
- jstimpfle 5y agoYou are probably referring to the defer() macro, which is well suited for some cases and not too unergonomic to use. I've used this for multiple years, and I still love it, together with X-macros they are some of the most important tricks I would advice any C programmer to try out. Sometimes with defer() you might get a difficult to read error message when you're doing something wrong, but it's galactically easier to deal with than the standard STL error spew that so many C++ programmers have just come to accept, and it's hard to do something wrong in the first place (just put simple expressions as arguments). A comparison of defer() with RAII is not that meaningful, as they are totally different things. RAII is this complicated system that leads to (requires) other more complicated stuff like {default,copy,move,assignment...}{constructor/destructors} as well as exceptions, with all sort of terrible interactions and implicit behaviour, that can easily get out of hand and make your code an unreadable mess and/or produce terribly inefficient (piece-meal allocations/function calls) and slow-compiling code (huge header includes). In the simple situations where defer() is a win, if you use (just) RAII instead, you always have to declare a class out-of-line first (using weird braces and all) to get ad-hoc behaviour, while with defer() macro you can just make something up on the spot, which is often a better way. I'm not saying there can't be experienced coders who use RAII well in some situations, but personally I opt to just not use it, since the price seems far to high for the benefits, outside of say primitive use in leetcode assignments.
- ogoffart 5y agoThe problem with defer is that it is a macro with all its problem. Imagine such code for (int i = 0; i < files_count; ++i) { file_handle_t handle = open_file(files[i]); defer(close_file(handle)) { // ... if (some_condition) { close_file(handle); break; } // ... } } But this doesn't work because you did not know or you forgot that `defer` was implemented with a `for` inside and so the `break` or `continue` goes out of the wrong loop. and that's just one example of the many thing that can go wrong because it is a macro. On the other hand, with RIAA, you just have your file_handle that automatically close so you can't forgot to close it, and the rules are well known and not that difficult to understand.
- jstimpfle 5y agoIt's indeed a problem that has happened to me, which is why I like to make the macro like for DEFER(init, exit) { } or at least give it a name that indicates clearly that this is syntactically a loop. That's like with some iteration macros that I like to use as well from time to time. The basic idea is to never try to hide what you're doing, since that will backfire. You can still take a balanced approach with DRY and separation of concerns principles, which can lead to reasonable macros. > and that's just one example of the many thing that can go wrong because it is a macro. I'm inclined to say that nothing can go wrong in above usage, or at the very least it would take criminal energy to break it (I really can't come up with a case right now). It's perfectly doable to write safe macros with only a little experience. Follow these simple rules when defining macros: 1) parenthesize usages of macro params, and parenthesize the whole macro body if it is a complete expression. 2) Use parameters that take syntactical expressions only once, to prevent evaluating side-effects (like x++) multiple times. Linux kernel even allows for declaration of local variables in macros by using expression statement blocks (GCC extension). Although I've never had a need for them, I believe that with this approach you can fulfill rule 2) in all possible situations. You can improve macro safety in cases where you need to define a macro that is a little dangerous by just capitalizing the macro's name to make clear at the call site to be a little bit careful here. The thing is, there is no need to be 100% safe. It's very good to be 99% safe and have a simple to use mechanism. Because there are always so many other ways to break your programming, and if you're trying to be 100% safe at the cost of being twice as hard to use, that's effectively a net loss because you're provoking problems in other ways. > On the other hand, with RIAA, you just have your file_handle that automatically close so you can't forgot to close it, and the rules are well known and not that difficult to understand. Could agree if it's a file handle or something other off-the-shelf thing where you don't have to make the class yourself, and everybody instinctively is aware of the implicit behaviour. Otherwise, I very much like the more explicit behaviour and ad-hoc convenience that a defer() macro gives me.