views:

1459

answers:

2

I want to create a C macro that creates a function with a name based on the line number. I thought I could do something like (the real function would have statements within the braces):

#define UNIQUE static void Unique_##__LINE__(void) {}

Which I hoped would expand to something like:

static void Unique_23(void) {}

That doesn't work. With token concatenation, the positioning macros are treated literally, ending up expanding to:

static void Unique___LINE__(void) {}

Is this possible to do?

(Yes, there's a real reason I want to do this no matter how useless this seems).

+5  A: 

I think you can get this to work with indirect macro expansion.

Ben Stiglitz
+11  A: 

The problem is that when you have a macro replacement, the preprocessor will only expand the macros recursively if neither the stringizing operator # nor the token-pasting operator ## are applied to it. So, you have to use some extra layers of indirection, you can use the token-pasting operator with a recursively expanded argument:

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void) {}

Then, __LINE__ gets expanded to the line number during the expansion of UNIQUE (since it's not involved with either # or ##), and then the token pasting happens during the expansion of TOKENPASTE.

It should also be noted that there is also the __COUNTER__ macro, which expands to a new integer each time it is evaluated, in case you need to have multiple instantiations of the UNIQUE macro on the same line.

Adam Rosenfield
I'm afraid that doesn't work with GNU cpp. TOKENPASTE uses __LINE__ as a literal. TOKENPASTE(Unique_, __LINE__) expands to Unique___LINE__
DD
@DD: D'oh, fixed now. It needs 2 layers of indirection, not 1.
Adam Rosenfield