Creating macro using __LINE__ for different variab

2019-01-25 06:31发布

问题:

Possible Duplicate:
Creating C macro with ## and LINE (token concatenation with positioning macro)

I am trying to use the __LINE__ macro to generate different variable names. I have a scoped benchmark class called Benchmark(located in the utils namespace) and it's constructor takes a string. Here is the macro definition I have created:

#define BENCHMARK_SCOPE utils::Benchmark bm##__LINE__(std::string(__FUNCTION__))

Unfortunately this causes the following error:

<some_file_name>(59): error C2374: 'bm__LINE__' : redefinition; multiple initialization

This leads me to the conclusion the __LINE__ macros does not get expanded. I have created my macross according to this post. Do you have ideas why __LINE__ does not get expanded?

EDIT: probably the compiler info is also relevent. I am using visual studio 2010.

回答1:

You need to use combination of 2 macros:

#define COMBINE1(X,Y) X##Y  // helper macro
#define COMBINE(X,Y) COMBINE1(X,Y)

And then use it as,

COMBINE(x,__LINE__);


回答2:

try this code, I've used it in an older project

#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#ifdef _MSC_VER // Necessary for edit & continue in MS Visual C++.
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __COUNTER__)
#else
# define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#endif 


int ANONYMOUS_VARIABLE(var)

EDIT:

I think you should use COUNTER in visual studio only if also using precompiled headers.



回答3:

You're using token pasting. This occurs before the recursive macro expansion (so that you can token paste to get the name of a macro you want to invoke). Thus:

#define PASTE(a,b) a ## b

will paste the exact arguments passed to PASTE, then try to expand the resulting new token. To get the effect you want, you need an additional level of indirection:

#define PASTE_HELPER(a,b) a ## b
#define PASTE(a,b) PASTE_HELPER(a,b)

Here, the arguments to PASTE will be expanded before PASTE_HELPER is invoked.