Create C macro C ## and __LINE__ (concatenate a marker using a positioning macro)

I want to create a C macro that creates a function named based on line number. I thought I could do something like (the real function will have expressions in braces):

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

I was hoping this would expand to something like:

 static void Unique_23(void) {} 

This does not work. When combining markers, positioning macros are processed literally, ending with the extension to:

 static void Unique___LINE__(void) {} 

Can this be done?

(Yes, there is a real reason I want to do this, no matter how useless it is).

+83
c macros concatenation token
Oct 20 '09 at 20:11
source share
2 answers

The problem is that when replacing macros, the preprocessor will recursively expand the macros if neither the streaming operator # nor the ## operator are applied to it. Thus, you should use some additional layers of indirection, you can use the insert statement with a recursively extended argument:

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

Then __LINE__ expands to the line number during the UNIQUE extension (since this is not associated with either # or ## ), and then the TOKENPASTE extension occurs when the marker is TOKENPASTE .

It should also be noted that there is also a __COUNTER__ macro, which, with each calculation, expands to a new integer if you need to have several instances of the UNIQUE macro on the same line. Note: __COUNTER__ supported by MS Visual Studio, GCC (since V4.3) and Clang, but is not standard C.

+145
Oct 20 '09 at 20:33
source share

GCC does not require “wrapping” (or implementation) unless the result is “wall”. Gcc has functions, but EVERYTHING can be run with a simple version of C version 1 (and some argue that Berkeley 4.3 C is much faster than learning how to use it).

** Clang (llvm) DOES NOT USE WHITE SPACE for macro expansion - it adds spaces (which, of course, destroy the result as C identifier for further preprocessing) **, clang just does not # or * Macro expansion as C preprocessor is expected for decades . The first example is X11 compilation, the "Concat3" macro is broken, resulting in a MISNAMED C Identifier, which, of course, cannot be created. and I start by building assemblies - this is their profession.

I think the answer here is “new C, which breaks the standards, it's bad C”, these hacks always choose (clobber namespaces), they change the default values ​​for no reason, but they don’t actually improve C (except for their own statements: I say that this is a device to explain why they leave all breakdowns for which no one forced them to answer).




It is not a problem that earlier C pre-processors did not support UNIq _ () __, because they supported #pragma, which allows "hacking compiler brands in code to be marked as hacking", as well as a function as well as FREE standards: as well how changing defaults is a useless wonton breakdown, and just like changing what a function does when using the same name (namespace plexus) is ... malware, in my opinion

-2
Mar 15 '17 at 1:43 on
source share



All Articles