How can I create a locally unique identifier name?

I want to create a unique variable name on the fly.

This is my code:

int call(int i) { return i; } #define XCAT3(a, b, c) a ## b ## c #define CALL_2(arg, place, line) int XCAT3(cl, place, line) = call(arg); #define CALL_1(arg) CALL_2(arg, __FUNCTION__, __LINE__) int main(int argc, char* argv[]) { CALL_1(1); /* this is line 20 */ return 0; } 

This works in GCC ( http://ideone.com/p4BKQ ), but unfortunately not in Visual Studio 2010 or 2012.

Error message:

test.cpp (20): error C2143: syntax error: missing ';' before 'function_string'

test.cpp (20): error C2143: syntax error: missing ';' before the "constant"

test.cpp (20): error C2106: '=': the left operand must be l-value

How to create a unique variable name on the fly using C ++?

Decision:

 #define CAT2(a,b) a##b #define CAT(a,b) CAT2(a,b) #define UNIQUE_ID CAT(_uid_,__COUNTER__) int main(int argc, char* argv[]) { int UNIQUE_ID = 1; int UNIQUE_ID = 2; return 0; } 
+4
source share
2 answers

For a unique identifier, many implementations offer the __COUNTER__ preprocessor __COUNTER__ , which expands to an increasing number with every use.

 #define CAT(a,b) CAT2(a,b) // force expand #define CAT2(a,b) a##b // actually concatenate #define UNIQUE_ID() CAT(_uid_,__COUNTER__) auto UNIQUE_ID() = call(1); // may be _uid_0 auto UNIQUE_ID() = call(2); // may be _uid_1 
+3
source

You need to defer the use of the marker until the place and line parameters are recursively expanded in the CALL_LATER2 macro. You do this by moving ## operations to a separate macro β€” until ## appears in the body of CALL_LATER2 , all its arguments will be pre-copied for the macros:

 #define XCAT3(a, b, c) a ## b ## c #define CALL_LATER2(fun, h, place, line) \ auto XCAT3(calllater, place, line) = \ call_later((fun), (h)); 

However, it still won’t do what you want, since __FUNCTION__ expands the string with the characters " , and not what can be inserted into the identifier. Instead, you just need to create your created name __LINE__ and make sure that you you can get duplicates in different compilation units, this is not a problem (if they are local to any function, this should be good, or you can put them in an anonymous namespace.)

+2
source

Source: https://habr.com/ru/post/1437467/


All Articles