Как заключить аргумент в макрос? - PullRequest
10 голосов
/ 15 января 2010

Я хотел бы создать макрос препроцессора C , который будет заключать аргумент в одну кавычку Так же, как обычно используется #X.

Я хочу, чтобы Q(A) был расширен до 'A'.

Я использую gcc в Linux.

У кого-нибудь есть идея?

Я знаю # двойные кавычки. Я ищу похожий механизм для одинарных кавычек.

Ответы [ 5 ]

14 голосов
/ 15 января 2010

Лучшее, что вы можете сделать, это

#define Q(x) ((#x)[0])

или

#define SINGLEQUOTED_A 'A'
#define SINGLEQUOTED_B 'B'
...
#define SINGLEQUOTED_z 'z'

#define Q(x) SINGLEQUOTED_##x

Это работает только для a - z, A - Z, 0 - 9 и _$ для некоторых компиляторов).

5 голосов
/ 15 января 2010

На самом деле, #X двойные кавычки своего аргумента, как вы можете видеть из следующего кода.

#define QQ(X) #X
char const * a = QQ(A);

Запустите это с gcc -E (чтобы увидеть только вывод препроцессора), чтобы увидеть

# 1 "temp.c"
# 1 "<built-n>"
# 1 "<command line>"
# 1 "temp.c"

char * a = "A"

Чтобы заключить в кавычки ваш аргумент (что в C означает, что это один символ), используйте подписку

#define Q(X) (QQ(X)[0])
char b = Q(B);

, который будет преобразован в

char b = ("B"[0]);
4 голосов
/ 15 января 2010

Лучшее, что я могу придумать, будет

#define Q(A) (#A[0])

но это не очень красиво, по общему признанию.

1 голос
/ 06 февраля 2013

Я только что попробовал объединение:

#define APOS           '
#define CHAR2(a,b,c)   a##b##c
#define CHAR1(a,b,c)   CHAR2(a,b,c)
#define CHAR(x)        CHAR1(APOS,x,APOS)

К сожалению, препроцессор жалуется на неопределенный символ. (и мультисимвол, если у вас более одного персонажа) Способ просто отключить ошибки препроцессора: (для этого нет специальной опции предупреждения)

-no-integrated-cpp -Xpreprocessor -w

Пример оптимизации во время компиляции с некоторыми другими приемами:

#define id1_id       HELP
#define id2_id       OKAY

#define LIST(item,...) \
    item(id1, ##__VA_ARGS__)\
    item(id2, ##__VA_ARGS__)\
    item(id1, ##__VA_ARGS__)\

#define CODE(id,id2,...)    ((CHAR(id##_id) == CHAR(id2##_id)) ? 1 : 0) +
int main() { printf("%d\n", LIST(CODE,id1) 0); return 0; }

Возвращает «2», поскольку есть два элемента с идентификатором1.

1 голос
/ 01 декабря 2010

генерирует конверсии:

#python
for i in range(ord('a'), ord('n')):
    print "#define BOOST_PP_CHAR_%s '%s'" % (chr(i), chr(i))

и это препроцессорная часть:

#ifndef BOOST_PP_CHAR_HPP
#define BOOST_PP_CHAR_HPP

#define BOOST_PP_CHAR(c) BOOST_PP_CHAR_ ## c
//  individual declarations    

#endif // BOOST_PP_CHAR_HPP
...