#define call_foo(...) \
do { \
int first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
....
int main(void) {
call_foo(first=9, third=5, second=3);
}
Obtención de valores de retorno de una manera torpe no es más difícil.
Esto permitirá hacer cosas muy tontas (que odio), tales como especificar valores predeterminados para sus argumentos:
#define call_foo(...) \
do { \
int first = default_first; \
int second; \
int third; \
(__VA_ARGS__); \
foo(first, second, third); \
} while (0)
Esto se producirá un error si lo hace:
int first = 9;
call_foo(first=first, third=5, second=3);
porque en la macro expansión first=first
significará inicializar el first
local consigo mismo. Pensé en tratar de evitar esto con la concatenación del preprocesador, pero eso se vuelve más complicado. Debería enumerar el mismo número de parámetros de macro como parámetros de función.
#define call_foo(x, y , z) \
do { \
int call_foo_first; \
int call_foo_second; \
int call_foo_third; \
call_foo_##x; \
call_foo_##y; \
call_foo_##z; \
foo(call_foo_first, call_foo_second, call_foo_third); \
} while (0)
La línea call_foo_##x;
se convertiría en call_foo_first=first;
si es llamado en el ejemplo anterior, por lo que cada símbolo tiene su propio nombre único. Esto hace que el truco del argumento predeterminado sea más incómodo porque tendría que especificar algo para completar ese punto en la lista de argumentos de macros.
Si la macro se define con un argumento predeterminado para first
a continuación:
call_foo(first, third=7, second=8);
Esto obliga a enumerar todos los parámetros (o al menos algo que se traduce en C legal - que podría haber enumerado dos veces segundo, pero podrías haberlo hecho de todos modos) para usar esta macro.
Creo que debería poder extender la última versión de esto para las macros/funciones enumeradas de argumento variable, pero los parámetros opcionales aún tendrían que pasarse al final de la lista y tendría que usar todos los los puntos obligatorios antes de llegar a los argumentos opcionales.
Me gusta esto. Muy creativo y limpio. – nategoose
Tenga en cuenta que con este método es imposible diferenciar un argumento cero/NULO de un argumento omitido. – caf