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).
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. Note: __COUNTER__
is supported by MS Visual Studio, GCC (since V4.3), and Clang, but is not standard C.
GCC doesn\'t require \"wrapping\" (or realizing) unless the result needs to be \"stringified\". Gcc has features but ALL can be done with plain C version 1 (and some argue Berkeley 4.3 C is so much faster it\'s worth learning how to use).
**Clang (llvm) DOES NOT DO WHITE SPACE CORRECTLY for macro expansion - it adds whitespace (which certainly destroy\'s the result as being a C Identifier for further pre-processing) **, clang simply doesn\'t do # or * macro expansion as a C Preprocessor is expected to for decades. The prime example is compiling X11, macro \"Concat3\" is broken, it\'s result is now MISNAMED C Identifier, which of course fails to build. and i\'m beginning to thing build fails are their profession.
I think the answer here is \"new C that breaks standards is bad C\", these hacks always choose to (clobber namespaces) they change defaults for no reason but do not really \"improve C\" (excepting to their own say so: which i say is contraption made to explain why they get away with all the breakage no one yet has made them responsible for).
It\'s not a problem that the earlier C pre-processors did not support UNIq_()__ because they supported #pragma which allows \"compiler brand hackery in code to be flagged as hackery\" and also function just as well WITHOUT effecting standards: just as changing defaults is useless wonton breakage, and just as changing what a function does while using the same name (namespace clobbering) is ... malware in my opinion