No puede hacer eso si USUARIO se define como una cadena entre comillas.
Pero usted puede hacer eso si el USUARIO es sólo JACK o reina o Joker o lo que sea.
Hay dos trucos para usar:
- Empalme de tokens, donde se combina un identificador con otro identificador simplemente concatenando sus caracteres. Esto te permite comparar con JACK sin tener que
#define JACK
hacerlo.
- expansión de macro variadic, que le permite manejar macros con números variables de argumentos. Esto le permite expandir identificadores específicos en diferentes números de comas, que se convertirán en su comparación de cadenas.
Así que comencemos con:
#define JACK_QUEEN_OTHER(u) EXPANSION1(ReSeRvEd_, u, 1, 2, 3)
Ahora, si escribo JACK_QUEEN_OTHER(USER)
, y USER es JACK, el preprocesador lo convierte enEXPANSION1(ReSeRvEd_, JACK, 1, 2, 3)
El segundo paso es la concatenación:
#define EXPANSION1(a, b, c, d, e) EXPANSION2(a##b, c, d, e)
Ahora se JACK_QUEEN_OTHER(USER)
convierte enEXPANSION2(ReSeRvEd_JACK, 1, 2, 3)
Esto da la oportunidad de agregar una serie de comas según si una cadena coincide o no:
#define ReSeRvEd_JACK x,x,x
#define ReSeRvEd_QUEEN x,x
Si USUARIO es JACK, se JACK_QUEEN_OTHER(USER)
convierte enEXPANSION2(x,x,x, 1, 2, 3)
Si USUARIO es REINA, se JACK_QUEEN_OTHER(USER)
convierte enEXPANSION2(x,x, 1, 2, 3)
Si USUARIO es otro, se JACK_QUEEN_OTHER(USER)
convierte enEXPANSION2(ReSeRvEd_other, 1, 2, 3)
En este punto, ha sucedido algo crítico: el cuarto argumento de la macro EXPANSION2 es 1, 2 o 3, dependiendo de si el argumento original pasado fue jota, reina o cualquier otra cosa. Así que todo lo que tenemos que hacer es elegirlo. Por razones extensas, necesitaremos dos macros para el último paso; serán EXPANSION2 y EXPANSION3, aunque una parezca innecesaria.
Poniéndolo todo junto, tenemos estas 6 macros:
#define JACK_QUEEN_OTHER(u) EXPANSION1(ReSeRvEd_, u, 1, 2, 3)
#define EXPANSION1(a, b, c, d, e) EXPANSION2(a##b, c, d, e)
#define EXPANSION2(a, b, c, d, ...) EXPANSION3(a, b, c, d)
#define EXPANSION3(a, b, c, d, ...) d
#define ReSeRvEd_JACK x,x,x
#define ReSeRvEd_QUEEN x,x
Y podrías usarlos así:
int main() {
#if JACK_QUEEN_OTHER(USER) == 1
printf("Hello, Jack!\n");
#endif
#if JACK_QUEEN_OTHER(USER) == 2
printf("Hello, Queen!\n");
#endif
#if JACK_QUEEN_OTHER(USER) == 3
printf("Hello, who are you?\n");
#endif
}
Enlace obligatorio de Godbolt: https://godbolt.org/z/8WGa19