It'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.