Jack
Jack

Reputation: 16724

error: pasting "." and "red" does not give a valid preprocessing token

I'm implementing The X macro, but I have a problem with a simple macro expansion. This macro (see below) is used into several macros usage examples, by including in this article. The compiler gives an error message, but I can see valid C code by using -E flag with the GCC compiler.

The macro X-list is defined as the following:

#define LIST \
  X(red, "red") \
  X(blue, "blue") \
  X(yellow, "yellow")

And then:

#define X(a, b) foo.##a = -1;
  LIST;
#undef X

But the gcc given the following errors messages:

lixo.c:42:1: error: pasting "." and "red" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "blue" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "yellow" does not give a valid preprocessing token

Like I said, I can seen valid C code by using -E switch on gcc:

lixo.c:42:1: error: pasting "." and "red" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "blue" does not give a valid preprocessing token
lixo.c:42:1: error: pasting "." and "yellow" does not give a valid preprocessing token
  foo.red = -1; foo.blue = -1; foo.yellow = -1;;

What's a valid preprocessing token? Can someone explain this?

(before you say "why not just an either initialize or memset()?" it's not my real code.)

Upvotes: 54

Views: 55335

Answers (3)

Jean Yne
Jean Yne

Reputation: 1

In some circumstances this could be a solution:

Replace

#define X(a, b) foo.##a = -1;

by

#define X(a, b) foo.color_##a = -1;

The result (without warning or error) is:

foo.color_red = -1;

With this method the preprocessor concatenate token color_ with token red. It is up to you to decide whether it’s acceptable to have color_red instead of red

Note: you can replace the prefix color_ by any other valid variable name, including just _

Upvotes: 0

Dmitry Grigoryev
Dmitry Grigoryev

Reputation: 3203

Notably, the GCC documentation says your example should compile, albeit with a warning:

two tokens that don’t together form a valid token cannot be pasted together. For example, you cannot concatenate x with + in either order. If you try, the preprocessor issues a warning and emits the two tokens.

However, as you have noticed, invalid tokens in macros result in an error since GCC 4.3 (circa 2008).

Upvotes: 0

Pubby
Pubby

Reputation: 53037

. separates tokens and so you can't use ## as .red is not a valid token. You would only use ## if you were concatenating two tokens into a single one.

This works:

#define X(a, b) foo.a = -1;

What's a valid proprocessing token? Can someone explain this?

It is what gets parsed/lexed. foo.bar would be parsed as 3 tokens (two identifiers and an operator): foo . bar If you use ## you would get only 2 tokens (one identifier and one invalid token): foo .bar

Upvotes: 66

Related Questions