48

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
  • 698,132
  • 130
  • 858
  • 1,229
Jack
  • 15,539
  • 54
  • 145
  • 264

1 Answers1

58

. 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
  • 50,432
  • 13
  • 129
  • 175
  • 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
  • @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