Hacker News new | past | comments | ask | show | jobs | submit login

A preprocessor "trick" not mentioned in the article is the use of GNU statement expressions.

The article describes the do {} while(0) trick to make macros look like statements. They can then basically be used like inline void function calls. But what if you want to write a macro to replace an inline function that returns a result?

Statement expressions [1] solve that problem. Now you can finally do this:

    int _foo(int x) { return 2 * x; }

    #ifdef __DEBUG__
    #   define foo(x) \({                     \
            int r = _foo(x);                  \
            printf(                           \
                "foo returned: %d (%s:%d)\n", \
                r, __FILE__, __LINE__         \
            );                                \
            r;                                \
        })
    #else
    #   define foo _foo
    #endif
They are supported by most popular compilers which are not made by Microsoft (including GCC and clang).

[1] https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html




The canonical use of which being safe min/max:

    #define min(a, b) ({ \
      __typeof__(a) _a = (a); \
      __typeof__(b) _b = (b); \
      _a > _b ? _b : _a; \
    })

    #define max(a, b) ({ \
      __typeof__(a) _a = (a); \
      __typeof__(b) _b = (b); \
      _b > _a ? _b : _a; \
    })
which avoid evaluating their arguments twice.


> A preprocessor "trick" not mentioned in the article is the use of GNU statement expressions.

That's probably because IAR sells compilers (and IDEs) for embedded software. IAR and Keil are the popular compilers in the "bare bones microcontroller C/Assembly" world.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: