Den Unterschied zwischen f () und f (void) in C und C ++ ein für allemal verstehen
Ok, also ich habe gehört, verschiedene Meinungen zu diesem Thema und wollen einfach nur sicherstellen, dass ich es richtig verstehe.
Für C++
Erklärungen void f();
und void f(void);
bedeuten genau das gleiche, die Funktion f
keine Parameter. Das gleiche gilt für Definitionen.
Für C
Erklärung void f(void);
bedeutet, dass f
keine Parameter.
Erklärung void f();
bedeutet, dass die Funktion f
möglicherweise oder möglicherweise nicht über Parameter, und wenn es das tut, wissen wir nicht, welche Parameter das sind, oder wie viele es von Ihnen ist. Beachten Sie, dass es ist NICHT das gleiche wie Ellipse, wir können nicht va_list
.
Nun, hier ist, wo die Dinge interessant.
Fall 1
Erklärung:
void f();
Definition:
void f(int a, int b, float c)
{
//...
}
Fall 2
Erklärung:
void f();
Definition:
void f()
{
//...
}
Frage:
Was geschieht bei der Kompilierung in den Fällen 1 und 2, wenn wir rufen f
mit den richtigen Argumenten, falschen Argumente und nicht-Argumente? Was geschieht zur Laufzeit?
Zusätzliche Frage:
Wenn ich erkläre f
mit Argumenten, sondern definieren es ohne Sie, wird es einen Unterschied machen? Sollte ich in der Lage, die Argumente von der Funktion Körper?
InformationsquelleAutor der Frage | 2012-11-10
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mehr Terminologie (C, nicht C++): ein Prototyp für eine Funktion deklariert, die Typen Ihrer Argumente. Sonst ist die Funktion nicht haben, ist ein Prototyp.
Erklärungen, die nicht Prototypen sind holdovers aus der vor-ANSI-C, von den Tagen der K&R C. Der einzige Grund für die Verwendung einer old-style-Deklaration aufrecht zu erhalten, die binäre Kompatibilität mit altem code. Zum Beispiel, in Gtk 2 gibt es eine Funktion, Erklärung, ohne ein Prototyp-es gibt es durch Zufall, aber es nicht entfernt werden kann, ohne zu brechen binaries. Der C99-standard Kommentare:
Empfehlung: ich schlage vor, in denen alle C-code in GCC/Clang mit
-Wstrict-prototypes
und-Wmissing-prototypes
zusätzlich zu den üblichen-Wall -Wextra
.Was passiert
Der Erklärung nicht einverstanden mit der Funktion Körper! Dies ist eigentlich ein compile-Zeit Fehler, und es ist, weil Sie nicht haben eine
float
argument in eine Funktion ohne Prototyp. Der Grund, warum Sie nicht verwenden können, einefloat
in einem unprototyped Funktion ist, weil beim Aufruf einer solchen Funktion, alle Argumente erhalten, gefördert über bestimmte Standard-Aktionen. Hier ist eine Feste Beispiel:In diesem Programm
a
wird gefördertint
1 undc
wird gefördertdouble
. So die definition fürf()
werden:Sehen C99 6.7.6 Absatz 15,
Antwort 1
Beim Aufruf
f()
die Parameter steigt mit der Standard-promotions. Wenn die geförderten Arten übereinstimmung der tatsächlichen parameter-Typen fürf()
dann ist alles gut. Wenn Sie nicht übereinstimmen, wird es wahrscheinlich kompilieren, aber Sie werden auf jeden Fall zu undefiniertem Verhalten."Undefined behavior" wird spec-sprechen für "wir machen keine Garantien über das, was geschehen wird." Vielleicht wird Ihr Programm Abstürzen, vielleicht wird es funktionieren, vielleicht wird es laden Sie Ihre Schwiegereltern zum Abendessen.
Gibt es zwei Möglichkeiten für die Diagnostik zur compile-Zeit. Wenn Sie eine anspruchsvolle compiler mit Kreuz-Modul statische Analyse-Funktionen, dann werden Sie wahrscheinlich eine Fehlermeldung erhalten. Sie können auch Nachrichten für un-Prototyp-Deklarationen mit GCC, mit
-Wstrict-prototypes
-- ich empfehle dem einschalten in alle Ihre Projekte (mit Ausnahme von Dateien, die Verwendung von Gtk 2).Antwort 2
Sollte es nicht kompilieren.
Ausnahmen
Gibt es tatsächlich zwei Fälle, in denen die Funktion Argumente zulässig sind, nicht einverstanden mit der definition einer Funktion.
Ist es okay, pass
char *
um eine Funktion, die erwartet, dassvoid *
und Umgekehrt.Ist es okay, pass eine vorzeichenbehaftete Ganzzahl-Typ auf eine Funktion, die erwartet, dass die unsigned-version geben, oder Umgekehrt, so lange der Wert darstellbar ist in beiden Arten (D. H., es ist nicht negativ, und nicht aus der Reichweite des unterzeichneten Typ).
Fußnoten
1: Es ist möglichdass
char
fördert zuunsigned int
aber das ist sehr selten.InformationsquelleAutor der Antwort Dietrich Epp
Die ganze Sache ist wirklich ein strittiger Punkt, wenn Sie C99 oder später (und, es sei denn, du stehst auf ein altes embedded-system oder so etwas wie, dass Sie wahrscheinlich sollte werden mit etwas mehr modern).
C99/C11 Abschnitt
6.11.6 Future language directions, Function declarators
Staaten:Daher sollten Sie es vermeiden, Dinge wie
void f();
insgesamt.Wenn es dauert, Parameter, Liste Sie hier auf, Sie bilden ein richtiges Vorbild. Wenn nicht, uns
void
zu zeigen definitiv, dass es nimmt keine Parameter.InformationsquelleAutor der Antwort paxdiablo
In C++,
f() und f(void) ist die gleiche
In C,
Sie sind anders, und eine beliebige Anzahl von Argumenten übergeben werden kann, während die aufrufende Funktion f() aber kein argument übergeben werden kann in f(void)
InformationsquelleAutor der Antwort rs2012
In reinem C, das zu dem Fehler führt:
error C2084: function 'void __cdecl f(void )' already has a body
.
Aber in Reinem C++ wird kompiliert ohne Fehler.
Überladen von Funktionen (nur C++, C hat keine überlastung)
Überlastung name einer Funktion f, indem er erklärt mehr als eine Funktion mit dem Namen f im gleichen Umfang. Die Erklärungen von f muss, unterscheiden sich von einander durch die Art und/oder die Anzahl der Argumente in der Argumentliste. Beim Aufruf einer überladenen Funktion mit dem Namen f, die richtige Funktion ausgewählt ist, indem Sie vergleichen die Liste der Argumente des Funktionsaufrufs mit der Liste der parameter von jedem der überladenen Kandidat Funktionen mit dem Namen f.
Beispiel:
Ausgabe:
InformationsquelleAutor der Antwort Software_Designer