BEZEICHNUNG
stdarg, va_start, va_arg, va_end, va_copy - variable Argument-Listen
ÜBERSICHT
#include <stdarg.h>
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);
BESCHREIBUNG
Eine Funktion kann mit einer unterschiedlichen Anzahl von Argumenten verschiedenen Typs aufgerufen werden. Die Include-Datei stdarg.h deklariert einen Typ va_list und definiert drei Makros, um eine Liste von Argumenten durchzugehen, deren Anzahl und Typen der aufgerufenen Funktion unbekannt sind.
Die aufgerufene Funktion muss ein Objekt des Typs va_list deklarieren, welches von den Makros va_start(), va_arg() und va_end() benutzt wird.
va_start()
Das Makro va_start() initialisiert ap zur
nachfolgenden Benutzung durch va_arg() und
va_end() und muss zuerst aufgerufen werden.
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.
va_arg()
Das Makro va_arg() expandiert zu einem Ausdruck, der
den Typ und Wert des nächsten aufzurufenden Argumentes
hat. Das Argument ap ist die va_list
ap, initialisiert durch va_start(). Jeder
Aufruf von va_arg() verändert ap so, dass
der folgende Aufruf das nächste Argument
zurückgibt. Der Parameter typ ist ein Typenname,
der so angegeben ist, dass der Typ eines Zeigers auf ein
Objekt, das den angegebenen Typ hat, einfach durch
Hinzufügen eines * zu typ erhalten werden
kann.
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_end()
Zu jedem Aufruf von va_start() muss zu einen
zugehörigen Aufruf von va_end() in der gleichen
Funktion geben. Nach dem Aufruf
va_end(ap) ist die Variable ap
undefiniert. Es sind mehrere Durchläufe der Liste
möglich, jeweils von va_start() und
va_end() eingeschlossen. va_end() kann ein
Makro oder eine Funktion sein.
va_copy()
Das Makro va_copy() kopiert die (vorher
initialisierte) Variablenargumentliste quelle nach
ziel. Das Verhalten ist so, als ob va_start()
auf ziel mit dem selben Argument letztes
angewandt worden wäre, gefolgt von der gleichen Anzahl
Aufrufe von va_arg(), die benutzt wurden, um den
aktuellen Status von quelle zu erreichen.
Eine naheliegende Implementierung hätte eine va_list, die ein Zeiger in den »Stack-Frame« der variadischen Funktion wäre. In einem derartigen Szenario (dem bei weitem üblichsten) scheint nichts gegen folgende Zuweisung zu sprechen
va_list aq = ap;
Leider gibt es auch Systeme, die es als Feld von Zeigern (der Länge 1) anlegen. Dort wird dann folgendes benötigt:
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.
ATTRIBUTE
Siehe attributes(7) für eine Erläuterung der in diesem Abschnitt verwandten Ausdrücke.
KONFORM ZU
Die Makros va_start(), va_arg() und va_end() sind konform zu C89. C99 definiert das Makro va_copy().
FEHLER
Im Gegensatz zu den historischen Makros varargs erlauben die Makros stdarg dem Programmierer nicht, eine Funktion ohne feste Argumente zu implementieren. Das ist hauptsächlich ein Problem, wenn man Code mit varargs nach stdarg konvertiert, aber es erzeugt auch Schwierigkeiten bei veränderlichen Funktionen die wünschen, ihre Argumente an eine Funktion weiterzugeben, die ein Argument va_list aufnimmt, so wie vfprintf(3).
BEISPIELE
Die Funktion foo nimmt eine Zeichenkette von Formatzeichen entgegen und gibt für jedes Zeichen ein Argument des entsprechenden Typs aus.
#include <stdio.h> #include <stdarg.h> void foo(char *fmt, …) /* ’…’ ist C-Syntax für eine variadische Funktion */ { va_list ap; int d; char c, *s; va_start(ap, fmt); while (*fmt) switch (*fmt++) { case 's': /* Zeichenkette */ s = va_arg(ap, char *); printf("string %s\n", s); break; case 'd': /* Ganzzahl */ d = va_arg(ap, int); printf("int %d\n", d); break; case 'c': /* 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); }
SIEHE AUCH
vprintf(3), vscanf(3), vsyslog(3)
KOLOPHON
Diese Seite ist Teil der Veröffentlichung 5.07 des Projekts Linux-man-pages. Eine Beschreibung des Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Patrick Rother <krd [AT] gulu.net>, Chris Leick <c.leick [AT] vollbio.de> und Helge Kreutzmann <debian [AT] helgefjell.de> erstellt.
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 [AT] lists.org>.