|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Hi,
I am just stumbled by a problem about concatenation in macro. See below code snippet: // there're some contants definition in this class struct X { enum {A, B, C}; }; // and here I want to define a utility macro to me generate some functions #define MK_FUNC(arg) \ int get##arg() \ { \ return X::##arg; \ } MK_FUNC(A) MK_FUNC(B) MK_FUNC(C) #undef MKFUNC // then I can use getA(), getB() .... in my program. But the preprocessor always complains: warning: pasting "::" and "A" does not give a valid preprocessing token warning: pasting "::" and "B" does not give a valid preprocessing token warning: pasting "::" and "C" does not give a valid preprocessing token I really don't why this will happen. Isn't this usage in the macro "X::##arg" an invalid ? Hope someone can me out. - Martin |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
cppcraze wrote:
> Hi, > > I am just stumbled by a problem about concatenation in macro. See > below code snippet: > > // there're some contants definition in this class > struct X > { > enum {A, B, C}; > }; > > // and here I want to define a utility macro to me generate some > functions > #define MK_FUNC(arg) \ > int get##arg() \ > { \ > return X::##arg; \ > } > > MK_FUNC(A) > MK_FUNC(B) > MK_FUNC(C) > > #undef MKFUNC > > // then I can use getA(), getB() .... in my program. > > But the preprocessor always complains: > > warning: pasting "::" and "A" does not give a valid preprocessing > token > warning: pasting "::" and "B" does not give a valid preprocessing > token > warning: pasting "::" and "C" does not give a valid preprocessing > token > > I really don't why this will happen. Isn't this usage in the macro > "X::##arg" an invalid ? Hope someone can me out. > The token pasting operator ## creates a new identifier. Since in the X:: sequence, arg is an independent identifier, and not pasted to anything (like "get"), just use X::arg, and it will expand properly. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
cppcraze a écrit :
> Hi, > > I am just stumbled by a problem about concatenation in macro. See > below code snippet: > > // there're some contants definition in this class > struct X > { > enum {A, B, C}; > }; > > // and here I want to define a utility macro to me generate some > functions > #define MK_FUNC(arg) \ > int get##arg() \ > { \ > return X::##arg; \ > } > > MK_FUNC(A) > MK_FUNC(B) > MK_FUNC(C) > > #undef MKFUNC > > // then I can use getA(), getB() .... in my program. > > But the preprocessor always complains: > > warning: pasting "::" and "A" does not give a valid preprocessing > token > warning: pasting "::" and "B" does not give a valid preprocessing > token > warning: pasting "::" and "C" does not give a valid preprocessing > token > > I really don't why this will happen. Isn't this usage in the macro > "X::##arg" an invalid ? Hope someone can me out. > > - Martin THe ## is used to make a new *single* token from two others. Since ::##arg gives (e.g. for A) ::A which is not a single token. |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Jan 18, 3:58 am, cppcraze <cppcr...@gmail.com> wrote:
> I am just stumbled by a problem about concatenation in macro. See > below code snippet: > // there're some contants definition in this class > struct X > { > enum {A, B, C}; > }; > // and here I want to define a utility macro to me generate some > // functions > #define MK_FUNC(arg) \ > int get##arg() \ > { \ > return X::##arg; \ > } > MK_FUNC(A) > MK_FUNC(B) > MK_FUNC(C) > #undef MKFUNC > // then I can use getA(), getB() .... in my program. > But the preprocessor always complains: > warning: pasting "::" and "A" does not give a valid preprocessing > token > warning: pasting "::" and "B" does not give a valid preprocessing > token > warning: pasting "::" and "C" does not give a valid preprocessing > token > I really don't why this will happen. Isn't this usage in the macro > "X::##arg" an invalid? It's invalid. The string "X::##arg" breaks down into the tokens X, ::, ## and arg. You're trying to paste :: and arg to get a single token, and that isn't a valid token in C++. Why do you paste at all here? Isn't the token you want precisely the expansion of arg?. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Jan 18, 4:54 am, red floyd <no.s...@here.dude> wrote:
[...] > The token pasting operator ## creates a new identifier. Not necessarily a new identifier. For example, I've used it for things like: op ## = where the legal values of op were +, -, etc. The only real requirement is that the results form a legal token. -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
![]() |
| Outils de la discussion | |
|
|