54

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.)

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Jack
  • 16,276
  • 55
  • 159
  • 284

2 Answers2

63

. 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

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • 9
    So is the section "Pasting tokens" in [this article](http://www.cprogramming.com/tutorial/cpreprocessor.html) is simply wrong? – Michael Jun 24 '14 at 07:53
  • @QuentinUK Didn't know it would work on Visual Studio. Maybe some of them isn't stricty C standard. – Jack Feb 02 '17 at 19:21
  • 1
    @QuentinUK There's only one definition of what's right and wrong (literally, that's the purpose of a standard), but sometimes a programmer is not the only part of the toolchain who meets the criteria of being wrong ;) – Lightness Races in Orbit Jul 19 '19 at 16:31
0

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).

Dmitry Grigoryev
  • 3,156
  • 1
  • 25
  • 53