Provided by: manpages-de-dev_2.5-1_all bug

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.

       ┌──────────────────────┬───────────────────────┬─────────────────┐
       │SchnittstelleAttributWert            │
       ├──────────────────────┼───────────────────────┼─────────────────┤
       │va_start(), va_end(), │ Multithread-Fähigkeit │ MT-Safe         │
       │va_copy()             │                       │                 │
       ├──────────────────────┼───────────────────────┼─────────────────┤
       │va_arg()              │ Multithread-Fähigkeit │ MT-Safe race:ap │
       └──────────────────────┴───────────────────────┴─────────────────┘

KONFORM ZU

       Die Makros va_start(), va_arg() und va_end() sind konform zu C89. C99 definiert das  Makro
       va_copy().

ANMERKUNGEN

       Diese  Makros  sind  nicht  kompatibel mit den historischen Makros, die sie ersetzen. Eine
       abwärtskompatible Version kann in der Include-Datei <varargs.h> gefunden werden.

       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.

FEHLER

       Im Gegensatz zu den 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).

BEISPIEL

       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, …)
       {
           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);
       }

KOLOPHON

       Diese  Seite  ist  Teil  der  Veröffentlichung  4.15  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@gulu.net> und
       Chris Leick <c.leick@vollbio.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@lists.debian.org>.

                                        15. September 2017                              STDARG(3)