15

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.

4
  • Hmm. Have you tried bm## __LINE__ (with a space)? Commented Apr 30, 2012 at 7:04
  • @Cameron I did thanks to your comment but nothing has changed. Commented Apr 30, 2012 at 7:05
  • OK, one more hack to try: #define _BENCHMARK_SCOPE(line) utils::Benchmark bm##line(... with #define BENCHMARK_SCOPE _BENCHMARK_SCOPE(__LINE__) Commented Apr 30, 2012 at 7:08
  • @Cameron - still not working. Here is an example on ideone: ideone.com/5r5l1 (tried to make it as simple as possible) Commented Apr 30, 2012 at 7:14

3 Answers 3

19

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__);
Sign up to request clarification or add additional context in comments.

2 Comments

Do you have an idea of why do I need to use two macros for that?
@izomorphius, Actually your question is a duplicate of another one, where it is explained nicely. I have commented that to your question, plz check it.
6

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.

Comments

5

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.

1 Comment

It worked with LINE as well.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.