A problem about concatenation in macro

C

cppcraze

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 help 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 help me out.

- Martin
 
R

red floyd

cppcraze said:
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 help 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 help 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.
 
J

jalina

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 help 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 help 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.
 
J

James Kanze

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 help me generate some
// functions
#define MK_FUNC(arg) \
int get##arg() \
{ \
return X::##arg; \
}

#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?.
 
J

James Kanze

[...]
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top