"Fossies" - the Fresh Open Source Software archive 
void va_start( va_list ap, letztes);
type va_arg( va_list ap, typ);
void va_end(va_list ap);
void va_copy(va_list ziel, va_list quelle);
Die aufgerufene Funktion muss ein Objekt des Typs va_list deklarieren, welches von den Makros va_start(), va_arg() und va_end() benutzt wird.
Das Argument letztes ist der Name des letzten Arguments vor der Liste der veränderlichen Argumente, das heisst, das letzt Argument, dessen Typ die aufrufende Funktion kennt.
Da die Adresse dieses Parameters im Makro va_start() benutzt wird, sollte er nicht als eine Registervariable, als Funktion oder als ein Feldtyp deklariert werden.
Die erste Benutzung des Makros va_arg() nach va_start() gibt das Argument nach letztes zurück. Nachfolgende Aufrufe geben die Werte der verbleibenden Argumente zurück.
Wenn es kein weiteres Argument gibt oder wenn typ nicht kompatibel mit dem Typ des tatsächlich nächsten Argumentes ist (entsprechend der üblichen »argument promotions«), erscheinen zufällige Fehler.
Falls ap an eine Funktion übergeben wird, die va_arg(ap,type) benutzt, dann ist der Wert von ap nach der Rückkehr dieser Funktion undefiniert.
va_list aq = ap;Leider gibt es auch Systeme, die es als Feld von Zeigern (der Länge 1) anlegen und ein solches benötigen.
va_list aq; *aq = *ap;Zu guter Letzt kann es auf Systemen, die Argumente in Registern übergeben, nötig sein, dass va_start Speicher reserviert und in diesem die Argumente und einen Positionsanzeiger speichert, so dass va_arg() diese Liste durchschreiten kann. Dann kann va_end() den reservierten Speicher wieder freigeben. Um dieser Situation Rechnung zu tragen, fügt C99 ein Makro va_copy() hinzu, so dass obige Zuweisung durch Folgendes ersetzt werden kann
va_list aq; va_copy(aq, ap); ... va_end(aq);Zu jedem Aufruf von va_copy() muss zu einen zugehörigen Aufruf von va_end() in der gleichen Funktion geben. Einige Systeme, die kein va_copy() bereitstellen, haben stattdessen __va_copy, da das der gleiche Name ist, der im ursprünglichen Vorschlag benutzt wurde.
Die historische Einstellung ist:
#include <varargs.h>
void
foo(va_alist)
va_dcl
{
va_list ap;
va_start(ap);
while (...) {
...
x = va_arg(ap, type);
...
}
va_end(ap);
}
Auf einigen Systemen enthält va_end eine abschließende »}«, die zu
einer »{« in va_start passt, so dass beide Makros in der gleichen Funktion
auf eine Weise erscheinen müssen, die dies möglicht.
#include <stdio.h>
#include <stdarg.h>
void
foo(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case aqsaq: /* Zeichenkette */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case aqdaq: /* Ganzzahl */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case aqcaq: /* Zeichen */
/* hier wird eine Typumwandlung benötigt, da va_arg
nur vollständig unterstützte Typen aufnimmt */
c = (char) va_arg(ap, int);
printf("Zeichen %c\n", c);
break;
}
va_end(ap);
}
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an <debian-l10n-german@lists.debian.org>.