Можете ли вы использовать вставленный токен в макросе? - PullRequest
33 голосов
/ 04 августа 2010

В макросе C возможно ли вставить прописной токен в заглавные буквы? Например, у меня в настоящее время есть следующий макрос:

#define TEST(name, keyword) \
    test_##name:
        TEST_##keyword##_KEYWORD

Я бы назвал это следующим образом:

TEST(test1, TEST1)

, что приведет к следующему:

test_test1:
    TEST_TEST1_KEYWORD

Теперь вместо того, чтобы вводить одно и то же имя дважды (один раз со всеми символами нижнего регистра и снова со всеми символами верхнего регистра), есть ли способ, которым я мог бы выполнить одно из следующих действий, и либо изменить маркер на все заглавные буквы или все строчные буквы?

TEST(test1) or TEST(TEST1)

Спасибо, Райан

Ответы [ 3 ]

13 голосов
/ 04 августа 2010

Насколько мне известно, единственными операциями, которые можно выполнять над токенами в препроцессоре C (по крайней мере, стандартом ISO / ANSI), является их замена, «строковое преобразование» или конкатенация. Я также не знаю ни о каких расширениях GCC или MSVC, которые позволят вам делать то, что вы хотите.

Однако люди придумывают хитрые (или странные) способы делать магические (или ужасные) вещи с помощью макросов, поэтому я не удивлюсь, если меня кто-нибудь удивит.

9 голосов
/ 04 августа 2010

Вы можете сделать что-то вроде следующего (непроверенное, возможно, опечатки ...)

#define NORMALIZE(TOK) NORMALIZE_ ## TOK

, а затем для каждой записи, которая может произойти, выполните

#define NORMALIZE_test1 test1
#define NORMALIZE_TEST1 test1

и затем используйтемакрос NORMALIZE внутри вашего реального макроса что-то вроде

#define TEST(name, keyword)                    \
    test_ ## NORMALIZE(name):                  \
        TEST_ ## NORMALIZE(keyword) ##_KEYWORD

(но, возможно, вам придется делать некоторые промежуточные вспомогательные макросы, пока вы не получите все конкатенации правильно)

2 голосов
/ 05 апреля 2016

Это невозможно, потому что препроцессор работает с входным потоком pp-token и не имеет конструкции, которая позволяла бы вам разложить их осмысленным образом.

То, что имеет препроцессор, - это конструкции для замены pp-tokens с расширениями макросов, объединить их, удалить их (целиком) и т. д.

Это означает, что ваша единственная надежда на верхний регистр состоит в том, чтобы начать с отдельных символов и прописных букв, а затем склеить все вместе.Прописывание отдельных символов довольно просто, поскольку у вас есть только ограниченный набор для работы.Склеивание их с другой стороны было бы возможно, по крайней мере, если вы ограничите себя фиксированной максимальной длиной.В конечном итоге вы получите макрос, который будет использоваться следующим образом:

TEST(t,e,s,t,1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...