views:

634

answers:

2

Why wont this work?

 0. #define CONCAT(x, y) x ## y
 1. 
 2. #define VAR_LINE(x) \
 3.     int CONCAT(_anonymous, __LINE__) = x
 4. 
 5. #define VAR_LINE2(x) \
 6.     int _anonymous ## x = 1
 7.
 8. int main()
 9. {
10.     VAR_LINE(1);
11.     VAR_LINE(1);
12.     VAR_LINE(1);
13.     VAR_LINE2(__LINE__);
14. }

The result from the above macro expansion

int _anonymous__LINE__ = 1;
int _anonymous__LINE__ = 1;
int _anonymous__LINE__ = 1;
int _anonymous13 = 1;

It would be convenient if I didn't have to write that __LINE__ macro as an argument.

I'm thinking the problem is pretty clear. I want to be able to generate anonymous variables so that this macro doesn't fail with redefinition error when declaring several variables within the same scope. My idea was to use the predefined __LINE__ macro because no variable will ever be declared on the same line like this. But the macro expansion troubles me, can you help?

Update: Correct answer

Thanks to Luc Touraille. However, there was a tiny problem with the suggested solution. There has to be whitespace between the operands and the ## operator (apparently the standard says otherwise but the the PS3 flavoured GCC would not expand the macro properly if there were no whitespace between the operator and operands).

#define _CONCAT(x,y) x ## y
#define CONCAT(x,y) _CONCAT(x,y)

The VAR_LINE macro now yields:

int _anonymous10 = 1;
int _anonymous11 = 1;
int _anonymous12 = 1;

This has been verified to work under Win32 (Visual Studio 2008), XBOX360 (Xenon) and PS3.

+3  A: 

This thread seems to investigate this issue. In short, it has to do with the order in which the various expansions are made. The suggested fix is to add another level of macro calls.

unwind
+8  A: 

You nee to add a level of indirection so that __LINE__ will be expanded:

#define _CONCAT_(x,y) x ## y
#define CONCAT(x,y) _CONCAT_(x,y)

#define VAR_LINE(x) int CONCAT(_anonymous, __LINE__) = x
Luc Touraille
Here's the deal, there's a problem with your suggested solution. There has to be whitespace between the operands and the ## operator. Your suggested solution should read #define _CONCAT_(x,y) x ## y.
John Leidegren
Well this is weird, the standard specifically states that "Space around the # and ## tokens in the macro definition is optional." (16.3.5 par.6). Anyway, I'll edit my answer accordingly.
Luc Touraille
Indeed it is, I checked this with people at work as well. Apparently the PS3 flavoured GCC would not expand the macro properly if there were no whitespace between the operator and operands.
John Leidegren