wake-up-neo.com

Wie erstelle ich ein variables Makro (variable Anzahl von Argumenten)

Ich möchte ein Makro in C schreiben, das eine beliebige Anzahl von Parametern akzeptiert, nicht eine bestimmte Anzahl

beispiel:

#define macro( X )  something_complicated( whatever( X ) )

dabei steht X für eine beliebige Anzahl von Parametern

Ich brauche das, weil whatever überladen ist und mit 2 oder 4 Parametern aufgerufen werden kann.

Ich habe versucht, das Makro zweimal zu definieren, aber die zweite Definition hat die erste Definition überschrieben!

Der Compiler, mit dem ich arbeite, ist g ++ (genauer gesagt, mingw)

178
hasen

C99 Way, auch vom VC++ Compiler unterstützt.

#define FOO(fmt, ...) printf(fmt, ##__VA_ARGS__)
276
Alex B

__VA_ARGS__ ist die Standardmethode. Verwenden Sie keine compilerspezifischen Hacks, wenn dies nicht erforderlich ist.

Es ärgert mich sehr, dass ich den ursprünglichen Beitrag nicht kommentieren kann. In jedem Fall ist C++ keine Obermenge von C. Es ist wirklich albern, Ihren C-Code mit einem C++ - Compiler zu kompilieren. Tu nicht was Donny nicht tut.

33
cmccabe

Ich denke nicht, dass das möglich ist, du könntest es mit Doppelparens vortäuschen ... nur solange du die Argumente nicht einzeln brauchst.

#define macro(ARGS) some_complicated (whatever ARGS)
// ...
macro((a,b,c))
macro((d,e))
25
eduffy
#define DEBUG

#ifdef DEBUG
  #define PRINT print
#else
  #define PRINT(...) ((void)0) //strip out PRINT instructions from code
#endif 

void print(const char *fmt, ...) {

    va_list args;
    va_start(args, fmt);
    vsprintf(str, fmt, args);
        va_end(args);

        printf("%s\n", str);

}

int main() {
   PRINT("[%s %d, %d] Hello World", "March", 26, 2009);
   return 0;
}

Wenn der Compiler verschiedene Makros nicht versteht, können Sie PRINT auch mit einer der folgenden Methoden entfernen:

#define PRINT //

oder

#define PRINT if(0)print

Die erste Anweisung kommentiert die PRINT-Anweisung aus, die zweite verhindert die PRINT-Anweisung aufgrund einer NULL-if-Bedingung. Wenn die Optimierung aktiviert ist, sollte der Compiler niemals ausgeführte Anweisungen entfernen wie: if (0) print ("Hallo Welt"); oder ((nichtig) 0);

10
Symon

hier für g ++ erklärt, obwohl es Teil von C99 ist, sollte es für alle funktionieren

http://www.delorie.com/gnu/docs/gcc/gcc_44.html

kurzes Beispiel:

#define debug(format, args...) fprintf (stderr, format, args)
4
DarenW