2012-04-15 3 views
4

Angenommen, ich möchte eine Funktion erstellen, die eine variadische Argumentliste rekursiv analysiert, indem jeder Aufruf der Funktion das nächste Argument liest? Nachdem ich die va_list an die nächste Funktion übergeben habe, beabsichtige ich nicht mehr, die va_list in der aufrufenden Funktion zu verwenden. Ist der folgende Code ok:Ist es in Ordnung, die Argumente in einer va_list rekursiv zu analysieren?

void VarArgRecursive(va_list args) { 
    int nextArg = va_arg(args, int); 
    if(nextArg != -1) { 
     printf("Next arg %d\n", nextArg); 
     VarArgRecursive(args); 
    } 
} 

void VarArgFunc(int firstArg, ...) { 
    va_list args; 
    va_start(args, firstArg); 
    VarArgRecursive(args); 
    va_end(args); 
} 

int main (int argc, char * const argv[]) { 

    VarArgFunc(20, 12, 13, -1); 

    return 0; 
} 

Der Code kompiliert auf meinem System, und der Ausgang wird wie erwartet:

Next arg 12 
Next arg 13 

So ist diese Praxis in Ordnung? Ich habe die Liste durchsucht und festgestellt, dass nach der Übergabe der va_list an die nächste Funktion der Inhalt der va_list in der aufrufenden Funktion nicht definiert ist. Das sollte für meine Verwendung keine Rolle spielen, da ich die va_list nicht weiter verwenden werde, nachdem ich sie an die nächste (gut, eigentlich, die selbe) Funktion übergeben habe. Ich habe überprüft auch diese Seite:

http://c-faq.com/varargs/handoff.html

... was zeigt, dass meine Art und Weise der Übergabe des va_list auf die nächste Funktion ist OK. Was es nicht sagt, ist, ob es in Ordnung ist, die va_list nach dem Lesen eines Arguments zu einer anderen Funktion zu übergeben und zu erwarten, dass die aufgerufene Funktion das nächste Argument liest. Gibt es auf diese Frage C++ - spezifische Antworten, ist das auch in Ordnung, da es in einem C++ - Programm verwendet wird.

+0

Wenn Sie nach C++ fragen, markieren Sie C++. –

+0

Es wird dringend davon abgeraten, 'varargs' zu verwenden. benutze variadic templates, verfügbar in G ++ seit (IIRC) 4.5 - Ich benutze nur G ++, daher kann ich nichts über andere Compiler sagen, aber ich denke, dass alle Mainstream-Compiler - außer MSVC - bereits Unterstützung dafür haben. Aber mein Hauptpunkt: 'Varargs' ist böse. Deren Verwendung wurde für sehr lange Zeit entmutigt und nur der ernsthafte Gebrauch davon ist 'printf()' Familie. – Griwes

+0

@Matthew Flaschen: Ich habe es nicht C++ markiert, weil ich dachte, dass die Makros va_list und va_arg zur Sprache c gehören und nicht C++. Ich habe sogar darüber nachgedacht, dies in meinem Beitrag zu erklären. Ich bin ein c-Programmierer, der C++ lernt, also tendiere ich dazu, Dinge auf die Art und Weise zu tun. Ich wusste nicht, dass es in C++ anders geht. – Balthazar

Antwort

1

Sie können es beliebig oft übergeben, aber Sie können die va_list nicht mehr als einmal "verwenden". Wenn sie verbraucht wird, kann die va_list modifiziert werden und ihre Verwendung ist erneut undefiniertes Verhalten gemäß der C++ - Spezifikation.

Wenn Sie es mehrmals verwenden möchten, rufen Sie va_copy auf, um die va_list zu klonen, bevor Sie sie verwenden, und übergeben Sie dann die Kopie.

In Ihrem Fall ist jedoch, was Sie tun, akzeptabel. Das Problem tritt auf, wenn Sie versuchen, die va_list von Anfang an eine andere Funktion zu übergeben.

+0

OK, danke. Ich habe es abgewartet, um zu sehen, ob es irgendwelche Einwände gibt, aber ich sehe keine und habe es als akzeptiert markiert ... :) – Balthazar

Verwandte Themen