Übergeben einer Ellipse an eine andere variadische Funktion [duplicate]

Lesezeit: 3 Minuten

Benutzeravatar von Tim Post
Tim Post

Ich habe ungefähr 30 variadische Funktionen. Jeder akzeptiert einen Pfad als letztes Argument, zB:

bool do_foo(struct *f, int q, const char *fmt, ...)

In jeder Funktion muss ich überprüfen, ob das erweiterte Format kleiner oder gleich einer bestimmten Größe ist. Ich kopiere / füge denselben Codeabschnitt ein, um zu überprüfen, wie viele Zeichen vorhanden sind vsnprintf() nicht gedruckt, eingestellt errno entsprechend und aus dem Schreiben aussteigen.

Ich möchte dazu eine Funktion schreiben, die eine statisch zugewiesene (erweiterte) Zeichenfolge zurückgibt, von der bekannt ist, dass sie eine sichere Größe hat, oder eine neu initialisierte Zeichenfolge bei einem Fehler, die auf NULL geprüft werden könnte. Die Prüfungen müssen auch feststellen, ob der String ein absoluter oder relativer Pfad ist, was die sichere Größe des Strings beeinflusst. Es ist eine Menge doppelter Code und es fängt an zu stinken.

Gibt es eine Möglichkeit, den Inhalt der Auslassungspunkte vom Eintrag meiner Funktion an eine andere Funktion zu übergeben? Oder muss ich anrufen va_start() zuerst, und dann passieren die va_list zur Hilfsfunktion?

Bearbeiten:

Ich bin überhaupt nicht dagegen, das zu bestehen va_list an den Helfer, ich wollte mich nur vergewissern, dass nichts anderes existiert. Es scheint mir, dass der Compiler versteht, wo die variadischen Argumente beginnen, also war ich nur neugierig, ob ich ihm sagen könnte, dass er sie weitergeben soll.

  • Gibt es einen Grund, warum Sie die Übergabe der va_list an den Helfer ablehnen?

    – ojblass

    30. März 2009 um 4:17 Uhr

  • Ich musste ähnliche Dinge tun, musste aber ein paar der Argumente entfernen … war kein angenehmer Code zu pflegen.

    – ojblass

    30. März 2009 um 4:18 Uhr

Sie können nicht, Sie können die Argumente nur als übergeben va_list. Siehe die comp.lang.c FAQ.

Wenn Sie variadische Funktionen (d. h. Funktionen, die eine variable Anzahl von Argumenten annehmen) in C schreiben, sollten Sie im Allgemeinen zwei Versionen jeder Funktion schreiben: eine, die ein Auslassungszeichen (...) und eine, die a nimmt va_list. Die Version mit Auslassungspunkten sollte aufrufen va_startrufen Sie die Version auf, die a nimmt va_listAnruf va_end, und zurück. Es ist keine Codeduplizierung zwischen den beiden Versionen der Funktion erforderlich, da die eine die andere aufruft.

  • Wäre nett, wenn du den Code schreiben würdest.

    – Andreas Rasmussen

    19. August 2014 um 0:49 Uhr

  • Was soll ich tun, wenn ich etwas mit tun muss va_list zweimal? Normalerweise müsste ich anrufen va_end und va_start zwischen Verwendungen (ansonsten ist es UB), aber ich kann es nicht in einer Funktion aufrufen, die dauert va_list: ‘va_start’ used in function with fixed args.

    – rr-

    19. September 2015 um 15:25 Uhr

  • Macht nichts, habe es herausgefunden – ich muss es verwenden va_copy für jede weitere Nutzung.

    – rr-

    19. September 2015 um 15:37 Uhr

  • Code? Hier ist auch ein Ort, um anderen zu helfen!

    – Wassilis

    5. November 2018 um 16:14 Uhr

Benutzeravatar von qrdl
qrdl

Wahrscheinlich können Sie variadische Makros verwenden – wie folgt:

#define FOO(...)  do { do_some_checks; myfun(__VA_ARGS__); } while (0)

ACHTUNG! Variadic-Makros sind nur für C99 verfügbar

  • Ich habe mir diese angesehen, das erspart mir das Hinzufügen eines Wrappers um die Funktion, die tatsächlich das Schreiben durchführt.

    – Tim Post

    30. März 2009 um 6:28 Uhr

  • c99 ist kein Problem, mein Programm ist eher gcc / linux spezifisch

    – Tim Post

    30. März 2009 um 6:29 Uhr

Ich weiß nicht, ob dies hilft, Sie können auf die Variablen per Referenz zugreifen. Das ist ein ziemlich hinterhältiger Trick, aber leider erlaubt es Ihnen nicht, Auslassungspunkte in der endgültigen Funktionsdefinition zu verwenden.

#include <stdio.h>

void print_vars(int *n)
{
  int i;
  for(i=0;i<=*n;i++)
    printf("%X %d  ", (int)(n+i), *(n+i));
  printf("\n");
}

void pass_vars(int n, ...)
{
  print_vars(&n);
}

int main()
{
    pass_vars(4, 6, 7, 8, 0);
    return 0;
}

Auf meinem PC gibt es aus

$ ./a.out
BFFEB0B0 4  BFFEB0B4 6  BFFEB0B8 7  BFFEB0BC 8  BFFEB0C0 0

  • Nicht tragbar…

    – Aschepler

    23. Januar 2013 um 16:56 Uhr

Sie müssen va_list an den Helfer übergeben.

1417010cookie-checkÜbergeben einer Ellipse an eine andere variadische Funktion [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy