Funktionen mit variabler Parameteranzahl

Gast #250144
@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
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
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
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
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
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

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.