Ich bin mir nicht sicher, ob dies bei allen Compilern funktioniert, aber bei mir hat es bisher funktioniert.
void inner_func(int &i)
{
va_list vars;
va_start(vars, i);
int j = va_arg(vars);
va_end(vars); // Generally useless, but should be included.
}
void func(int i, ...)
{
inner_func(i);
}
Sie können das ... zu inner_func() hinzufügen, wenn Sie wollen, aber Sie brauchen es nicht. Es funktioniert, weil va_start die Adresse der angegebenen Variablen als Startpunkt verwendet. In diesem Fall geben wir ihm einen Verweis auf eine Variable in func(). Sie verwendet also diese Adresse und liest die nachfolgenden Variablen auf dem Stack. Die Funktion inner_func() liest von der Stack-Adresse von func(). Sie funktioniert also nur, wenn beide Funktionen das gleiche Stacksegment verwenden.
Die Makros va_start und va_arg funktionieren im Allgemeinen, wenn Sie ihnen eine beliebige var als Ausgangspunkt geben. Wenn Sie wollen, können Sie also Zeiger auf andere Funktionen übergeben und diese ebenfalls verwenden. Sie können Ihre eigenen Makros leicht genug erstellen. Alles, was die Makros tun, ist das Typisieren von Speicheradressen. Allerdings ist es lästig, sie für alle Compiler und Aufrufkonventionen zu erstellen. Daher ist es im Allgemeinen einfacher, die Makros zu verwenden, die mit dem Compiler geliefert werden.