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

Можете ли вы использовать залитый токен в макросе?

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

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

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

TEST(test1, TEST1)

который даст следующее:

test_test1:
    TEST_TEST1_KEYWORD

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

TEST(test1) or TEST(TEST1)

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

#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

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

Ответ 3

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

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

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

TEST(t,e,s,t,1)