¿Hay alguna manera de escribir macros con una lista de argumentos variables en Visual C++?
-
09-06-2019 - |
Pregunta
Hasta donde yo sé, en gcc puedes escribir algo como:
#define DBGPRINT(fmt...) printf(fmt);
¿Hay alguna manera de hacer eso en VC++?
Solución
Sí, pero sólo desde VC++ 2005.La sintaxis para su ejemplo sería:
#define DBGPRINT(fmt, ...) printf(fmt, __VA_ARGS__)
Una referencia completa es aquí.
Otros consejos
Sí, puede hacer esto en Visual Studio C++ en las versiones 2005 y posteriores (no estoy seguro acerca de VS 2003).Echa un vistazo a VA_ARGS.Básicamente puedes hacer algo como esto:
#define DBGPRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
y los argumentos variables de la macro se pasarán a la función proporcionada como argumentos '...', donde luego podrá usar va_args para analizarlos.
Puede haber comportamientos extraños con VA_ARGS y el uso de macros.Porque VA_ARGS es variable, eso significa que puede haber 0 argumentos.Eso podría dejarte con comas al final donde no era tu intención.
Si no desea utilizar extensiones no estándar, debe proporcionar corchetes adicionales:
#define DBGPRINT(args) printf(args);
DBGPRINT(("%s\n", "Hello World"));
Lo que estás buscando se llama [macros variables](http://msdn.microsoft.com/en-us/library/ms177415(VS.80).aspx).
Resumen del enlace:sí, desde VC++ 2005 en adelante.
Si realmente no necesita ninguna de las funciones de las macros (__FILE__
, __LINE__
, pegado de tokens, etc.) es posible que desee considerar escribir una función variada usando stdargs.h
.en lugar de llamar printf()
, una función variada puede llamar vprintf()
para pasar listas de argumentos variables.
Para MSVC 7.1 (.NET 2003), esto funciona:
#if defined(DETAILED_DEBUG)
#define DBGPRINT fprintf
#else
__forceinline void __DBGPRINT(...){}
#define DBGPRINT __DBGPRINT
#endif
Lo siguiente debería funcionar.(Ver enlace a Macros variadas)
(El siguiente ejemplo muestra argumentos fijos y variables).
# define DBGPRINTF(fmt,...) \
do { \
printf(fmt, __VA_ARGS__); \
} while(0)
Buscar "VA_ARGS" y va_list en MSDN!
Casi.Sin embargo, es más feo que eso (y probablemente no quieras un punto y coma final en la macro misma:
#define DBGPRINT(DBGPRINT_ARGS) printf DBGPRINT_ARGS // note: do not use '(' & ')'
Para usarlo:
DBGPRINT(("%s\n", "Hello World"));
(faltaban un par de padres).
No estoy seguro de por qué todos los aspectos negativos, la pregunta original no indicaba una versión de VC++, y no todos los compiladores admiten macros variadas.