Можете ли вы использовать залитый токен в макросе?
В макросе C можно ли загладить вставленный токен? Например, в настоящее время у меня есть следующий макрос:
#define TEST(name, keyword) \
test_##name:
TEST_##keyword##_KEYWORD
Я бы вызвал это следующим образом:
TEST(test1, TEST1)
который даст следующее:
test_test1:
TEST_TEST1_KEYWORD
Теперь вместо того, чтобы вводить одно и то же имя дважды (один раз со всеми строчными символами и снова со всеми символами верхнего регистра), есть ли способ, которым я мог бы сделать одно из следующих, и либо изменить токен на все заглавные буквы или все строчные буквы?
TEST(test1) or TEST(TEST1)
Спасибо,
Райан
Ответы
Ответ 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)