Подтвердить что ты не робот

Ошибка: вставка "." и "красный" не дает действительного токена предварительной обработки

Я реализую макрос X, но у меня проблема с простым расширением макроса. Этот макрос (см. Ниже) используется в нескольких примерах использования макросов, включая статью this.  Компилятор выдает сообщение об ошибке, но я могу видеть действительный код C, используя флаг -E с компилятором GCC.

Список макросов X определяется следующим образом:

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

И затем:

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

Но 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

Как я уже сказал, я могу видеть действительный код C с помощью -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;;

Какой действительный токен предварительной обработки? Может кто-нибудь объяснить это?

(прежде чем вы скажете "почему бы не просто инициализировать или memset()?" это не мой настоящий код.)

4b9b3361

Ответ 1

. разделяет токены, поэтому вы не можете использовать ##, поскольку .red не является допустимым токеном. Вы использовали бы только ##, если бы вы объединили два токена в один.

Это работает:

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

Какой действительный токен для обработки? Может кто-нибудь объяснить это?

Это то, что получает синтаксический анализ/лексирование. foo.bar будет анализироваться как 3 токена (два идентификатора и оператор): foo . bar Если вы используете ##, вы получите только 2 токена (один идентификатор и один недопустимый токен): foo .bar