¿Hay alguna manera de hacer que el preprocesador C (GCC) ejecute dos pases para expandir completamente las macros?
Estoy tratando de definir macros que admitan E/S de puerto en un microcontrolador usando nombres abstractos para pines:
#define LED_RED E, (1<<6) #define SetPin(port, mask) PORT ## port ## SET = (mask) #define ClearPin(port, mask) PORT ## port ## CLR = (mask) #define ReadPin(port, mask) (PORT ## port) & (mask)Luego en mi código:
SetPin(LED_RED); ClearPin(LED_RED); result = ReadPin(LED_RED);Esto está destinado a expandirse a:
PORTESET = (1<<6); PORTECLR = (1<<6); result = (PORTE) & (1<<6);Esto no se compila, obtengo:
error: la macro "SetPin" requiere 2 argumentos, pero solo se proporciona 1.
Aunque esto compila y funciona bien:
SetPin(E, (1<<6));Entonces... ¿cómo hacer que el compilador de C expanda completamente estas macros?
O, si no es eso, ¿cómo hacer que este tipo de cosas funcionen?
Tienes que pasar los argumentos a través de una macro adicional.
#define LED_RED E, (1<<6) #define SetPin2(port, mask) PORT ## port ## SET = (mask) #define SetPin(x) SetPin2(x) SetPin(LED_RED);Esto se debe al orden de reemplazo de macros:
## o # , se macroexpanden antes. Con la macro adicional "en el medio", el segundo paso tiene la oportunidad de reemplazar LED_RED .