Funktionen mit variabler Parameteranzahl

Gast #250144
Lesenswert?

@Rufus T. Firefly (Rufus)

nett, dass es Dich gibt...

@Ralf

Man kann auch einfach einen Pointer übergeben und dann die Bytes
zählen, die die einzelnen Parameter haben, schon mal was von Stack
gehört?

va_start und Konsorten blähen das Programm derart auf, dass man mit
wenig Flash dann nix mehr übrig hat.

va_start und Konsorten sind für embedded-programmig absolut ungeeignet,
da sie meistens als eierlegende Wollmilchsau implementiert
sind.
Persönliche Seite #250145
Lesenswert?

Da dieser Forenabschnitt "PC-Programmierung" genannt wird, ist nicht
auszuschließen, daß Ralf vielleicht doch etwas anderes als einen
Microcontroller programmieren möchte.

Der Vorteil von va_start und Konsorten ist deren Portabilität; direkte
Stackmanipulationen sind das nicht.

Einen Glückwunsch an Hubert:
Das ist der erste halbwegs konstruktive Beitrag von Dir! Geht doch!

Was exakt meinst Du mit

  "va_start und Konsorten blähen das Programm derart auf,
  dass man mit wenig Flash dann nix mehr übrig hat." ?

Könntest Du das mit Codegrößenbeispielen belegen?
Gast #250147
Lesenswert?

naochmal an Rufus T. Firefly (Rufus)@


Der Vorteil von va_start und Konsorten ist deren Portabilität; direkte
Stackmanipulationen sind das nicht.

Was fällt Dir an diesem Satz, Deinem Satz auf?
Gast #250148
Lesenswert?

Lustig finde ich ja, daß keine von euch die Frage gelesen zu haben
scheint. Es geht überhaupt nicht darum, wie man variable Argumentlisten
umsetzt, sondern woher die Funktion weiß, wieviele Argumenten man denn
übergeben hat.
Nun, dafür gibt es zwei übliche Wege. Entweder verwendet man eins der
festen Argmente, um daüber direkt (einfach ein Integer mit der Anzahl)
oder indirekt (wie z.B. bei printf über den Formatstring) an die Anzahl
zu kommen oder man benutzt einen speziellen Wert, den man als
Ende-Marker noch dranhängt.
Es gibt keine Möglichkeit, die Funktion so zu schreiben, daß sie
automatisch ohne Hilfe des Aufrufers die Anzahl erkennen kann.
Gast #250150
Lesenswert?

Erstmal ein Danke an alle.

@Rufus:

Es geht mir im allgemeinen um C an sich, im speziellen tatsächlich um
Microcontroller. Ob ich es mal auf PC-Seite brauche, will ich ja nicht
ausschließen, und da ich es eben für beides brauchen kann, hab ich es
extra ins Programmier- und nicht ins Elektronik-Forum gestellt.

Die Sache mit dem va_start und va_arg ist mir bekannt, nur wusste ich
eben nicht, wie ich darauf schließen kann, den letzten Parameter
erhalten zu haben.

@Hubert:

> Man kann auch einfach einen Pointer übergeben und dann die Bytes
> zählen, die die einzelnen Parameter haben, schon mal was von Stack
> gehört?

Habs noch nicht begriffen. Kannst du es bitte genauer erläutern,
vielleicht mit Beispiel?

Die Sache mit der Portabilität ist für das aktuelle Projekt nicht
wichtig, jedoch ist der Hinweis sehr nützlich. Ich kann mir vorstellen,
dass man es vergisst, portabel zu programmieren, wenn man auf beiden
Seiten (µC + PC) programmiert.

@Rolf:

Treffer! Du hast genau die Problematik erfasst (soll keine Kritik an
den anderen sein!).

Mal sehen, ob ich es begriffen habe. Möglichkeit 1, indirekt scheidet
denke ich aus, da ich nicht mit Format-Strings arbeiten möchte
(zumindest nicht im aktuellen Projekt).

Der direkte Weg ist mir noch nicht ganz klar. Der erste Parameter gibt
also die Anzahl der Parameter an. Mit va_start initialisiere ich den
Pointer, der auf die weiteren Argumente nach dem ersten Argument zeigt,
richtig?

Möglichkeit 2, mit Ende-Marker ist glaub ich auch nicht das richtige,
da es m.E. vor allem im µC-Bereich vorkommen kann, dass jeder mögliche
Wert als Parameter übergeben wird, also auch der Endemarker als Daten.

Also, ich denke, Möglichkeit 1, direkt ist das richtige für mich.

Ralf
Persönliche Seite #250151
Lesenswert?

Mit va_start bekommst du einen Wert zurückgegeben, den du nicht direkt
verwendest, sondern bei weiten Aufrufen von va_arg angibst. Damit holst
du die dann die Parameter. Den Typ der Parameter musst du für va_arg
wissen.

Beispiel:

void func( int anzahl, ... )
{
 va_list l;
 va_start( l, anzahl );
 for (int i = 0; i < anzahl; i++ )
   DoSomething( va_arg( l, int ) );
 va_end( l );
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren