Variabelt makro - förmågan hos C-förprocessorn att deklarera stöd för ett annat antal argument med hjälp av ett speciellt makro .
Variable -argument makron introducerades i ISO /IEC 9899:1999 ( C99 ) revisionen av C programmeringsspråksstandarden 1999. Sådana makron introducerades också i ISO/IEC 14882:2011 ( C++11 ) för C++ programmeringsspråket standard 2011 [1] .
Deklarationssyntaxen liknar den för en variadisk funktion : utelämnandet " ... " används för att indikera att noll eller fler argument kan skickas. När det utökas med ett makro ersätts varje anrop till den speciella identifieraren __VA_ARGS__ i makrots ersättningslista med de argument som skickas.
De individuella argumenten i den formella parameterlistan nås inte av värde eller genom hur de skickades.
I gcc kan listan med formella makroparametrar innehålla antingen specificerade argument eller alternativt skickade (se exempel).
GNU Compiler Collection sedan version 3.0, C++ Builder 2006 och Visual Studio 2005 [1] stödjer makron med variabelargument vid kompilering av både C- och C++-kod . Dessutom stöder GCC variabla makron vid kompilering av Objective-C- kod .
Om du behöver en printf - som dprintf () funktion som tar filnamnet och radnumret som det anropas från som ett argument, kan du använda följande makro:
void realdprintf ( char const * file , int line , char const * fmt , ...); #define dprintf(...) realdprintf(__FILE__, __LINE__, __VA_ARGS__)dprintf() kan kallas som:
dprintf ( "Hej världen" );som är vadderad till:
realdprintf ( __FILE__ , __LINE__ , "Hej världen" );eller:
dprintf ( "%d + %d =%d" , 2 , 2 , 5 );som är vadderad till:
realdprintf ( __FILE__ , __LINE__ , "%d + %d =%d" , 2 , 2 , 5 );Ett ofullständigt exempel återspeglar inte möjligheterna, jag lägger till:
#define CALL( _obj, _mtd, _specifiedArg1,_specifiedArg2, ... ) _obj->_mtd(_specifiedArg2,_specifiedArg1, __VA_ARGS__)sålunda är det möjligt att manipulera en del av de angivna argumenten, i exemplet är argumenten utbytta.
I vissa fall kan ett vanligt makroanrop fungera som ett alternativ till variadiska makron. Till exempel kan följande kod användas för felsökning :
#ifdef TRACING #define TRACE(_p) printf _p #else #define TRACE(_p) #endifOm TRACING-makrot definieras vid kompilering, kommer anrop av TRACE-makrot att vara likvärdigt med anrop av printf- funktionen :
TRACE (( "Kör rad %d \n " , __LINE__ ));Om TRACING-makrot inte har definierats kommer meddelandet inte att skrivas ut medan programmet körs. Observera att anropsparametrarna för detta makro måste omges av dubbla parenteser.
I vissa andra fall, istället för variadiska makron, kan du använda stdargs- funktionaliteten för C/C++-språken och anropet till vprintf-funktionen .
Ett annat exempel:
#if defined ( DEBUG_MCU ) #define TRACE( args ... ) printf( args ) #else #define TRACE( args ... ) #endif