Creating C macro with ## and __LINE__ (token concatenation with positioning macro)

后端 未结 2 1707
夕颜
夕颜 2020-11-22 10:28

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

相关标签:
2条回答
  • 2020-11-22 11:04

    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.

    0 讨论(0)
  • 2020-11-22 11:19

    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

    0 讨论(0)
提交回复
热议问题