Macros that evaluate their parameters more than once are dangerous for a variety of reasons.
On Wed, Jul 29, 2020 at 11:32 AM David Sidrane <david.sidr...@nscdg.com> wrote: > K&R warns against using macros in loops. Experienced programmers (especially > embedded) know not to write code like shown in the "reason" for needing this > change. True, but at the call site, use of a macro looks just like a function call, so good macro writing is to make sure it works just like a function call, no matter where it's used. Furthermore, over time, the implementation of a macro could change from macro to function, or from function to macro. Or you might build the application software on NuttX one day and on a PC OS the next. So if the macro ends up being used in a loop, it might not be because the programmer is inexperienced, but because the implementation (or the platform) changed after the code was written. Also, you don't know where/how these macros are being used. Perhaps someone is using a 3rd party library that uses these macros and assumes they are safe. Because of all these reasons, it is very important, when writing macros, to make sure they can be used in all possible scenarios without causing problems. That includes: * Evaluating parameters once. * If the macro is multiple statements, as opposed to an expression, wrapping those statements in do { ... } while (0). I think these things are the responsibility of the macro writer, not the macro caller. Regarding isalpha() and friends: On Wed, Jul 29, 2020 at 2:54 AM Xiang Xiao <xiaoxiang781...@gmail.com> wrote: > 2.Change macro to normal function and lose some performance > 3.Change macro to inline function and some old compilers may generate > the bloat code Given all of the above, and the various concerns voiced here, I think option 2 looks best/safest in the context of embedded systems. While some here might gawk at the performance penalty of a function call, I agree with Greg that: > Most released, deeply embedded software does not do a lot of string > processing. So I could imagine that a motor control system that only > has a couple of uses of ctype functions but would pay a pretty big size > penalty for using a table. I think function call overhead isn't quite as horrible as its reputation might suggest. In fact, if you have macros that evaluate their parameters more than once, you potentially get a much bigger performance penalty. (I just recently discovered use of min() and max() macros in code I maintain. Those are implemented as ((a) < (b)) ? (a) : (b). And the parameters passed to these macros at the call site were the results of function calls, those functions were making time-consuming calculations, and they were being executed redundantly because of the macros evaluating their parameters more than once! That is a much bigger performance penalty! On Wed, Jul 29, 2020 at 8:42 AM spudaneco <spudan...@gmail.com> wrote: > I would consider option 3 to be the worst choice. That could bloat can be > enormous and unacceptable as I have seen in the past. I saw growth by many > kbyte in such cases. Not a good compromise. I wonder if there exists a good solution for the inline function problem that will be C89 compliant, avoid the code bloat, and not create a maintenance nightmare. I don't know what that is yet, but if we find a solution, it will be helpful for other things besides the isalpha() (and friends) macros. Nathan