Nearly Hygienic C Macros via __COUNTER__

A few months back Benjamin Stiglitz taught me that it’s finally possible to build practically-hygienic macros with modern plain ol’ C #defines. Here’s his example:

#define MIN_PASTE(A,B) A##B
#define MIN_IMPL(A,B,L) ({ \
    __typeof__(A) MIN_PASTE(__a,L) = (A); \
    __typeof__(B) MIN_PASTE(__b,L) = (B); \
    MIN_PASTE(__a,L) < MIN_PASTE(__b,L) ? MIN_PASTE(__a,L) : MIN_PASTE(__b,L); \
})
#define MIN(A,B) MIN_IMPL(A,B,__COUNTER__)

So this C code:

int a = 11;
int b = 42;
int c = MIN(a, b);

preprocesses into this:

int a = 11;
int b = 42;
int c = ({
    __typeof__(a) __a0 = (a);
    __typeof__(b) __b0 = (b);
    __a0 < __b0 ? __a0 : __b0;
});

Here’s how __COUNTER__ works:

A new predefined macro __COUNTER__ has been added. It expands to sequential integral values starting from 0. In conjunction with the ## operator, this provides a convenient means to generate unique identifiers.

It’s still not gensym-quality, since the generated variable name can shadow other variable names:

int a = 11;
int b = 42;
int __a0 = a * b; // uh oh
int c = MIN(a, b);
assert(__a0 == 462); // passes though

This is contrived, since you probably aren’t going to prefix your variable names with double-underscores. That said, this code does compile and execute correctly, although enabling -Wshadow will reveal all is not well.

__COUNTER__ is supported by GGC 4.3, clang and even MSVC.

Nov 18 2011