Pregunta

Por ejemplo, es lo siguiente posible:

#define definer(x) #define #x?
¿Fue útil?

Solución

Aunque su sintaxis no es válida, la respuesta a su pregunta es técnicamente sí. Pero solo se puede lograr con trucos desagradables que hacen que su código sea ilegible e imposible de mantener.

Consulte también: http://www.ioccc.org/years.html#1995_vanschnitz y http://www.ioccc.org/years.html#2004_vik2

Otros consejos

No, no puedes hacer eso.
El símbolo de la libra (#) tiene un significado diferente mientras está en una definición. significa: si esto es un argumento, conviértalo en una cadena entre comillas.

No puede anidar directivas de preprocesador C. Afortunadamente, casi nunca es necesario. Si realmente necesita ese tipo de poder, seguramente estará mejor con otro preprocesador que ejecuta antes de entregar el código al compilador de C. Por ejemplo:

sed 's/@CUSTOMER@/J. Random Person/' foo.c.in > foo.c
cc foo.c

Otro truco útil es aislar el truco en un solo archivo de encabezado, que es generado por un programa que usted mismo escribe:

./generate-trickery --greet 'J. Random Person' > foo.h

donde foo.h se verá así:

#define GREET(x) ("J. Random Person greets you, " #x)

Si vincula esto con un Makefile, o alguna otra automatización, será bastante fluida y no dispara mucho tu desarrollo.

No, no puedes hacer eso.

Puede hacer referencia a una macro de otra, pero no puede definir una macro de otra.

Si está intentando crear un segmento de código de preprocesador que se puede llamar varias veces para realizar cosas ligeramente diferentes, una forma (moderadamente horrible) de hacerlo es aislar el código en un único archivo .h que luego #include varias veces. La idea es que cada vez que #define el archivo esté & Quot; llamando a su rutina & Quot; - usted " pasar argumentos " primero ENUMVAL() ing ciertas constantes de preprocesador a las que se refiere el archivo incluido.

Un lugar donde he visto que esto es útil es generar " smart " enumeraciones que pueden convertir a / desde su " stringized " formularios (que es útil para E / S). Crea un archivo enum que contiene, por ejemplo,

ENUMVAL(foo)
ENUMVAL(bar)
ENUMVAL(baz)

y luego <=> este archivo dos veces: una vez donde <=> se define de tal manera que se cree una declaración <=>, y una vez cuando <=> se define de tal manera que se produzca una matriz de nombres en cadena. Al hacerlo de esta manera, no necesita especificar la lista de tokens reales más de una vez.

#define definer(x) #define #x?

#x es una cadena de cadenas de x. No puede #definir un token de cadena. (#define " foo " ;.) Tiene que ser un identificador [a-zA-Z0-9 _] * token.

Usted no puede anidar # define así. No puede tener un #define en un #define.

Usted puede tener # if dentro de #if bloques.

#ifdef FOO

#ifdef BAR
 ...
#else // BAR
 ...
#endif // BAR

#else // FOO
 ...
#endif //FOO

También está algo limitado en cuanto a las expresiones que puede usar en #if macros. Pero a veces puedes evitar eso. Por ejemplo:

        /* Use CONCATENATE_4_AGAIN to expand the arguments to CONCATENATE_4 */
#define CONCATENATE_4(      a,b,c,d)  CONCATENATE_4_AGAIN(a,b,c,d)
#define CONCATENATE_4_AGAIN(a,b,c,d)  a ## b ## c ## d

    /* Creates a typedef that's legal/illegal depending on EXPRESSION.       *
     * Note that IDENTIFIER_TEXT is limited to "[a-zA-Z0-9_]*".              *
     * (This may be replaced by static_assert() in future revisions of C++.) */
#define STATIC_ASSERT( EXPRESSION, IDENTIFIER_TEXT)                     \
  typedef char CONCATENATE_4( static_assert____,      IDENTIFIER_TEXT,  \
                              ____failed_at_line____, __LINE__ )        \
            [ (EXPRESSION) ? 1 : -1 ]

Además de algo como:

STATIC_ASSERT( sizeof(int1) == 1, sizeof_int1_equal_1 );

(Sí, sé sobre #include < stdint.h > . Es solo un ejemplo.)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top