Funktionsüberladung in C

Lesezeit: 4 Minuten

Benutzer-Avatar
Andrej Ciobanu

Schauen Sie sich heute die Manpage für an open()habe ich bemerkt, dass diese Funktion “überladen” ist:

   int open(const char *pathname, int flags);
   int open(const char *pathname, int flags, mode_t mode);

Ich hätte nicht gedacht, dass es auf C möglich ist. Was ist der “Trick”, um dies zu erreichen?

SPÄTER BEARBEITEN:

Es ist also nicht wirklich überladen, denn wenn Sie varargs verwenden, können Sie nur mehrere Argumente desselben Typs angeben. Also ist mode_t hinter den kulissen ein int ?

  • mode_t ist zwar eine Ganzzahl, aber Sie können Argumente unterschiedlichen Typs angeben, vorausgesetzt, Sie wissen, wie man sie interpretiert. Die printf-Funktionsfamilie tut dies, indem sie den Format-String verwendet, um zu wissen, wie ihre zusätzlichen Argumente zu interpretieren sind, selbst wenn sie anders typisiert sind. Meine Antwort unten enthält einige Beispiele, die dies verdeutlichen könnten.

    – Eli Courtwright

    21. April 2010 um 19:41 Uhr


  • @Eli danke, ich muss das mit Java verwechselt haben.

    – Andrej Ciobanu

    21. April 2010 um 19:47 Uhr

  • Solche Funktionen nennt man variadische Funktionen.

    – Chris

    22. Januar 2012 um 19:22 Uhr

Benutzer-Avatar
Nr

Es benutzt variable Argumente. Diese Deklarationen erscheinen nur in der Manpage, da diese 2 die einzigen Möglichkeiten sind, open() aufzurufen. Die eigentliche C-Funktion wird als zB deklariert

int open(const char *pathname,int flags,...);

Bei variablen Argumenten müssen die Argumente nicht denselben Typ haben. printf ist das offensichtliche Beispiel dafür.

Im Fall von open() muss das erste Variablenargument mode_t sein, wenn ‘flags das O_CREAT-Flag enthalten, da die Implementierung von open() erwartet, dass es mode_t ist (was hinter den Kulissen wahrscheinlich ein unsigned int oder unsigned long ist – aber das hat nichts mit varargs zu tun)

Benutzer-Avatar
Eli Gerichtsschreiber

C macht es möglich, Funktionen mit a zu schreiben variable Anzahl von Argumentenwie zum Beispiel printf.

Abgesehen davon gibt es in C keine zuverlässige, plattformübergreifende Möglichkeit, eine Funktion zu schreiben, die genau 2 oder 3 Argumente akzeptiert. im Allgemeinen müssen Sie so etwas tun

some_function(5, 6, 7, NULL);
some_function(5, 6, 8, 2, 5, NULL);

Mit anderen Worten, Sie müssen ein abschließendes “Sentinal” -Argument haben. Alternativ könnten Sie die Anzahl der Parameter irgendwie in einen früheren Parameter einfügen, z

another_func(2, "hello", "world");
another_func(3, "goodbye", "cruel", "world");

Das printf Familien von Funktionen verfolgen diesen Ansatz; der erste Formatparameter enthält die Anzahl der benötigten zusätzlichen Parameter; zB mit printf("%f %f", 5.6, 7.11) Sie wissen, dass es 2 Float-Parameter geben muss. Allerdings wäre dies in einer benutzerdefinierten Bibliotheksfunktion etwas unsicher, da wenn Sie sagten my_printf("%s %f %f %f %s", 5.6) dann könnten Sie Segfaults oder Schlimmeres bekommen. Glücklicherweise prüfen die meisten C-Compiler Ihre Aufrufe von printf zur Kompilierzeit, um diese Art von Problemen zu vermeiden.

Im Falle des openwird die Funktion mit variablen Argumenten deklariert, und der dritte Parameter wird nur überprüft, wenn O_CREAT eingestellt ist. So wird also “sicher” festgestellt, ob ein drittes Argument vorhanden ist. Ich habe “sicher” in Anführungszeichen gesetzt, weil es für open technisch gesehen keine Möglichkeit gibt, zur Laufzeit zu wissen, wie viele Parameter tatsächlich übergeben wurden. Beispielsweise würden die folgenden Aufrufe ohne Fehler oder Warnungen kompiliert:

open("foo.txt", 5, "not an integer", 7);    // extra and invalid parameters
open("bar.txt", O_CREAT);                   // third parameter is missing

  • Wenn some_function() nimmt ints, Sie sollten es nicht mit beenden NULLwie NULL ist nur 0 im numerischen Kontext. NULL Terminatoren funktionieren am besten mit Zeigerparametern.

    – Chris Lutz

    21. April 2010 um 19:47 Uhr

  • @Chris: Guter Punkt, ich verwende im Allgemeinen NULL als Abschlusszeichen, unabhängig von Datentypen, aber Sie haben Recht, dass es verwirrend sein könnte, insbesondere für Leute, die nicht wissen, dass 0 und NULL gleich sind, da sie dies vielleicht denken könnte sowas schreiben some_func(3, 2, 1, 0, -1, NULL) obwohl dies tatsächlich dazu führen würde, dass 0 als Abschlussparameter fungiert.

    – Eli Courtwright

    21. April 2010 um 20:05 Uhr

  • Neuere Versionen von gcc und den glibc-Headern zusammen erzeugen eine Warnung für Ihre letzten beiden Beispiele.

    – Café

    21. April 2010 um 23:22 Uhr

“mode muss angegeben werden, wenn O_CREAT in den Flags steht, und wird ansonsten ignoriert.”

extern int open (__const char *__file, int __oflag, ...)

Es verwendet varargs und lädt nur das Modusvariablenargument, wenn __oflag enthält O_CREAT.

sehr kurze Antwort – varargs

Sie können es mit einer variablen Argumentliste mit vortäuschen ...

int function(int x, ...);

1365400cookie-checkFunktionsüberladung in C

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

Privacy policy