Durch das Schreiben foo(void)erreichen wir daher die gleiche Interpretation in beiden Sprachen und machen unsere Header mehrsprachig (obwohl wir normalerweise einige weitere Dinge mit den Headern tun müssen, um sie wirklich sprachübergreifend zu machen, nämlich sie in eine zu packen, extern "C"wenn wir sie kompilieren C ++).
Aber wenn C ++ das benötigt voidhätte, hätte es das Problem der "ärgerlichsten Analyse" vermeiden können.
Adrian McCarthy
5
Stimmt, aber es gibt so viele andere beschissene Parses in C ++, dass es keinen Sinn macht, über einen von ihnen zu kvetchen.
DrPizza
16
Auf eine aktuelle Frage hat @James Kanze einen interessanten Leckerbissen gepostet. Repost hier, um zu vermeiden, dass es verloren geht: In den ersten Versionen von C konnte die Anzahl der Parameter, die eine Funktion annehmen könnte, nicht angegeben werden. Dies void foo()war die einzige Syntax, die eine Funktion deklarierte. Bei der Einführung von Signaturen musste das C-Komitee den No-Parameter von der alten Syntax unterscheiden und die void foo(void)Syntax einführen . C ++ hat es aus Kompatibilitätsgründen verwendet.
Matthieu M.
3
Können Sie mir ein Beispiel für C C90 und höher geben, bei dem die Verwendung void foo()anstelle von C void foo(void)einen funktionalen Unterschied erzeugt? Dh ich benutze die Version seit vielen Jahren ohne die Leere und habe kein Problem gesehen, vermisse ich etwas?
Chacham15
6
@ chacham15 wird void foo() { if ( rand() ) foo(5); } kompiliert und ausgeführt (was zu undefiniertem Verhalten führt, es sei denn, Sie haben großes Glück), während void foo(void)bei demselben Text ein Kompilierungsfehler auftreten würde.
MM
39
Mir ist klar, dass sich Ihre Frage auf C ++ bezieht, aber wenn es um C geht, finden Sie die Antwort in K & R, Seiten 72-73:
Wenn eine Funktionsdeklaration keine Argumente enthält, wie in
double atof();
auch das bedeutet, dass über die Argumente von atof nichts anzunehmen ist; Alle Parameterprüfungen sind deaktiviert. Diese besondere Bedeutung der leeren Argumentliste soll es älteren C-Programmen ermöglichen, mit neuen Compilern zu kompilieren. Aber es ist eine schlechte Idee, es mit neuen Programmen zu verwenden. Wenn die Funktion Argumente akzeptiert, deklarieren Sie diese. Wenn keine Argumente erforderlich sind, verwenden Sie void.
Die Frage bezieht sich jedoch auf Definitionen. In diesem Fall lautet die relevante C-Regel. Eine leere Liste in einem Funktionsdeklarator, die Teil einer Definition dieser Funktion ist, gibt an, dass die Funktion keine Parameter hat.
Anhang C "Kompatibilität" C.1.7 Abschnitt 8: Die Anmelder sagen:
8.3.5 Änderung: In C ++ akzeptiert eine mit einer leeren Parameterliste deklarierte Funktion keine Argumente. In C bedeutet eine leere Parameterliste, dass Anzahl und Typ der Funktionsargumente unbekannt sind.
Beispiel:
int f();// means int f(void) in C ++// int f( unknown ) in C
Begründung: Dies dient dazu, fehlerhafte Funktionsaufrufe zu vermeiden (dh Funktionsaufrufe mit der falschen Anzahl oder Art von Argumenten).
Auswirkung auf das ursprüngliche Merkmal: Wechseln Sie zur Semantik eines genau definierten Merkmals. Diese Funktion wurde in C als "veraltet" markiert.
8.5.3 Funktionen sagt:
4. Die Parameterdeklarationsklausel bestimmt die Argumente, die angegeben werden können, und deren Verarbeitung, wenn die Funktion aufgerufen wird. [...] Wenn die Parameterdeklarationsklausel leer ist, akzeptiert die Funktion keine Argumente. Die Parameterliste (void) entspricht der leeren Parameterliste.
C99
Wie in C ++ 11 erwähnt, int f()gibt es nichts über die Argumente an und ist veraltet.
In C verwenden Sie eine Leere in einer leeren Funktionsreferenz, sodass der Compiler einen Prototyp hat und dieser Prototyp "keine Argumente" hat. In C ++ müssen Sie dem Compiler nicht mitteilen, dass Sie einen Prototyp haben, da Sie den Prototyp nicht auslassen können.
"Prototyp" bezeichnet die Argumentlistendeklaration und den Rückgabetyp. Ich sage das, weil "Prototyp" mich verwirrt hat, was Sie zuerst gemeint haben.
Antworten:
In C :
void foo()
bedeutet "eine Funktion,foo
die eine nicht spezifizierte Anzahl von Argumenten vom nicht spezifizierten Typ nimmt"void foo(void)
bedeutet "eine Funktionfoo
ohne Argumente"In C ++ :
void foo()
bedeutet "eine Funktionfoo
ohne Argumente"void foo(void)
bedeutet "eine Funktionfoo
ohne Argumente"Durch das Schreiben
foo(void)
erreichen wir daher die gleiche Interpretation in beiden Sprachen und machen unsere Header mehrsprachig (obwohl wir normalerweise einige weitere Dinge mit den Headern tun müssen, um sie wirklich sprachübergreifend zu machen, nämlich sie in eine zu packen,extern "C"
wenn wir sie kompilieren C ++).quelle
void
hätte, hätte es das Problem der "ärgerlichsten Analyse" vermeiden können.void foo()
war die einzige Syntax, die eine Funktion deklarierte. Bei der Einführung von Signaturen musste das C-Komitee den No-Parameter von der alten Syntax unterscheiden und dievoid foo(void)
Syntax einführen . C ++ hat es aus Kompatibilitätsgründen verwendet.void foo()
anstelle von Cvoid foo(void)
einen funktionalen Unterschied erzeugt? Dh ich benutze die Version seit vielen Jahren ohne die Leere und habe kein Problem gesehen, vermisse ich etwas?void foo() { if ( rand() ) foo(5); }
kompiliert und ausgeführt (was zu undefiniertem Verhalten führt, es sei denn, Sie haben großes Glück), währendvoid foo(void)
bei demselben Text ein Kompilierungsfehler auftreten würde.Mir ist klar, dass sich Ihre Frage auf C ++ bezieht, aber wenn es um C geht, finden Sie die Antwort in K & R, Seiten 72-73:
quelle
C ++ 11 N3337 Standardentwurf
Es gibt keinen Unterschied.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf
Anhang C "Kompatibilität" C.1.7 Abschnitt 8: Die Anmelder sagen:
8.5.3 Funktionen sagt:
C99
Wie in C ++ 11 erwähnt,
int f()
gibt es nichts über die Argumente an und ist veraltet.Es kann entweder zu Arbeitscode oder UB führen.
Ich habe den C99-Standard ausführlich interpretiert unter: https://stackoverflow.com/a/36292431/895245
quelle
In C verwenden Sie eine Leere in einer leeren Funktionsreferenz, sodass der Compiler einen Prototyp hat und dieser Prototyp "keine Argumente" hat. In C ++ müssen Sie dem Compiler nicht mitteilen, dass Sie einen Prototyp haben, da Sie den Prototyp nicht auslassen können.
quelle