Как одинарная кавычка аргумента в макросе?

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

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

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

Есть ли у кого-нибудь идеи?

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

Ответ 1

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

#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 и _$ для некоторых компиляторов).

Ответ 2

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

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

но это не очень мило, правда.

Ответ 3

Собственно, #X double цитирует свой аргумент, как вы можете видеть со следующим кодом.

#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

это создает преобразования:

#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

Ответ 5

Я просто попробовал конкатенацию:

#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)

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

-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", так как есть два элемента с id1.