Variabelt makro

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 5 juni 2018; kontroller kräver 4 redigeringar .

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] .

Deklarationssyntax

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).

Support

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 .

Exempel

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.

Alternativ

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) #endif

Om 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

Se även

Anteckningar

  1. Arbetsutkast till ändringar för C99-förprocessorsynkronisering - http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm Arkiverad 31 juli 2020 på Wayback Machine

Källor