2010-01-15 18 views
10

Me gustaría crear una macro de preprocesador C C que citará solo el argumento. Al igual que el común usado #X.¿Cómo se cita un argumento en una macro?

Quiero Q(A) ampliarse a 'A'.

Estoy usando gcc en Linux.

¿Alguien tiene una idea?

# comillas dobles. Estoy buscando un mecanismo similar para una sola cita.

Respuesta

13

Lo mejor que puede hacer es

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

o

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

#define Q(x) SINGLEQUOTED_##x 

esto sólo funciona para a - z, A - Z, 0 - 9 y _ (y $ para algunos compiladores).

+0

Oh, ese segundo método es puro mal ;-) – Joey

+1

'$' no es un carácter válido para un identificador, de acuerdo con el estándar C. Puede ser aceptado por algunos compiladores específicos, supongo. –

+0

@Dale: Sí, GCC admite '$' como identificador. http://gcc.gnu.org/onlinedocs/gcc/Dollar-Signs.html#Dollar-Signs – kennytm

4

Lo mejor que se me ocurre sería

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

pero esto no es muy bonito, es cierto.

4

En realidad, #X comillas dobles su argumento, como se puede ver con el siguiente código.

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

Ejecutar este con gcc -E (sólo ver la salida del preprocesador) para ver

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

char * a = "A" 

Para comilla su argumento (que en C significa que se trata de un solo carácter) utiliza subíndices

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

que se transformará en

char b = ("B"[0]); 
1

esto genera conversiones:

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

y esto es parte del preprocesador: concatenación

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

acabo intentado:

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

Lamentablemente, sin embargo, el preprocesador se queja de un sin terminar personaje.(Y de varios caracteres si tiene más de un carácter) una forma de errores sólo desactivar preprocesador: (no hay ninguna opción específica de advertencia para este)

-no-integrated-cpp -Xpreprocessor -w 

Algunos ejemplos de optimización en tiempo de compilación con algunos otros trucos:

#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; } 

Esto devuelve "2", ya que hay dos elementos que tienen id1.

Cuestiones relacionadas