Was ist der Unterschied zwischen function () und function (void)?

27

Ich habe gehört, dass es eine gute Praxis ist, Funktionen zu schreiben, die nichts als Parameter wie folgt erhalten:

int func(void);

Aber ich höre, dass der richtige Weg, das auszudrücken, so ist:

int func();

Was ist der Unterschied zwischen diesen beiden Funktionsdeklarationen in C und C ++?

Grizzly
quelle
5
Dies ist ein Duplikat von tausend anderen Fragen im Standortnetzwerk, unter anderem stackoverflow.com/questions/18167390/…
Lars Viklund
@LarsViklund es ist nur ein Duplikat, wenn es auf dieser Seite eine Frage gibt. Ich kann keine finden, unabhängig davon, was auf SO ist, ist dies kein Duplikat. Wahrscheinlich lohnt es sich, diese Frage als Wegweiser zu haben, wenn sonst nichts.
1
@LightnessRacesinOrbit haben wir im Chat besprochen und beschlossen, es mit einigen Änderungen beizubehalten .

Antworten:

17

C und C ++ unterscheiden sich in dieser Hinsicht.

C 2011 Online Standard

6.7.6.3 Funktionsdeklaratoren (einschließlich Prototypen)
...
10 Der Sonderfall eines unbenannten Parameters vom Typ voidals einziges Element in der Liste gibt an, dass die Funktion keine Parameter hat.
...
14 Eine Bezeichnerliste deklariert nur die Bezeichner der Parameter der Funktion. Eine leere Liste in einem Funktionsdeklarator, die Teil einer Definition dieser Funktion ist, gibt an, dass die Funktion keine Parameter hat. Die leere Liste in einem Funktionsdeklarator, die nicht Teil einer Definition dieser Funktion ist, gibt an, dass keine Informationen über die Anzahl oder den Typ der Parameter angegeben werden. 145)

Kurz gesagt, wird eine leere Parameterliste in einer Funktionsdeklaration zeigt an, dass die Funktion eine dauert unspezifiziert Anzahl der Parameter, während eine leere Parameterliste in einer Funktionsdefinition anzeigt , daß die Funktion übernimmt keine Parameter.

T foo( void ); // declaration, foo takes no parameters
T bar();       // declaration, bar takes an *unspecified* number of parameters

T foo( void ) { ... } // definition, foo takes no parameters
T bar() { ... }       // definition, bar takes no parameters

In Bezug auf C sollten Sie in einer Funktionsdeklaration oder -definition niemals eine leere Bezeichnerliste verwenden . Wenn eine Funktion keine Parameter annehmen soll, geben Sie dies voidin der Parameterliste an.

Online C ++ Standard

8.3.5 Funktionen [dcl.fct]
...
4 Die Parameterdeklarationsklausel bestimmt die Argumente, die beim Aufruf der Funktion angegeben und verarbeitet werden können. [ Anmerkung: Mit der Parameterdeklarationsklausel werden die beim Funktionsaufruf angegebenen Argumente konvertiert. siehe 5.2.2. - end note ] Wenn die Parameterdeklarationsklausel leer ist, akzeptiert die Funktion keine Argumente. Eine Parameterliste, die aus einem einzelnen unbenannten Parameter eines nicht abhängigen Typs voidbesteht, entspricht einer leeren Parameterliste. Mit Ausnahme dieses Sonderfalls darf ein Parameter keinen Typ haben cv void. Wenn die Parameter-Deklaration-Klauselendet mit einem Auslassungszeichen oder einem Funktionsparameterpaket (14.5.3), muss die Anzahl der Argumente gleich oder größer als die Anzahl der Parameter sein, die kein Standardargument haben und keine Funktionsparameterpakete sind. Wo syntaktisch korrekt und "..." nicht Teil eines Abstract-Deklarators ist , ist ", ..." gleichbedeutend mit "...". [ Beispiel: die Erklärung
    int printf(const char*, ...);
deklariert eine Funktion, die mit unterschiedlicher Anzahl und Art von Argumenten aufgerufen werden kann.
    printf("hello world");
    printf("a=%d b=%d", a, b);
Das erste Argument muss jedoch von einem Typ sein, der in ein const char*- end - Beispiel konvertiert werden kann. ] [ Hinweis: Der Standardheader <cstdarg>enthält einen Mechanismus für den Zugriff auf Argumente, die mit den Auslassungspunkten übergeben werden (siehe 5.2.2 und 18.10). - Endnote ]

Im Fall von C ++ gibt eine leere Parameterliste in einer Deklaration oder Definition an, dass die Funktion keine Argumente akzeptiert, und entspricht der Verwendung einer Parameterliste von void.

John Bode
quelle
35

In C, eine Funktion mit einer leeren Parameterliste ()kann nimmt etwas für ihre Argumente. Buchstäblich alles. Dies wird normalerweise verwendet, um eine Funktion zu implementieren, die eine variable Anzahl von Argumenten annehmen kann. Heutzutage wird jedoch die Verwendung der expliziteren Auslassungssyntax (...)für diese Funktionen als vorzuziehen angesehen .

In C nimmt eine Funktion mit der Parameterliste (void)explizit nichts für ihre Argumente. Das heißt, der Compiler kann Ihnen tatsächlich mitteilen, dass Sie einen Fehler gemacht haben, wenn Sie versuchen, etwas zu übergeben.

In C ++ sind diese Funktionsdeklarationen äquivalent. Eine leere Parameterliste bedeutet "keine Parameter", wie dies auch der voidFall ist.

Ixrec
quelle
Betreff: "Dies wird normalerweise verwendet, um eine Funktion zu implementieren, die eine variable Anzahl von Argumenten annehmen kann": Sind Sie sich da sicher? Ich glaube nicht, dass ich jemals ein Programm gesehen habe, das explizite Parameterlisten für Forward-Deklarationen von nicht variadischen Funktionen und ()für solche von variadischen Funktionen verwendet hat. Haben Sie ein Beispiel für ein Programm, das diese Konvention verwendet?
Ruakh
4
Eine variable AC-Funktion muss mit der ...Syntax definiert werden und mindestens einen benannten Parameter haben. Das Definieren einer solchen Funktion mit ()undefiniertem Verhalten führt dazu, dass der Hauptteil der Funktion die in definierten Makros nicht <stdarg.h>zum Lesen der Parameterwerte verwenden kann. Dies ist seit dem Standard 1989/1990 der Fall.
Keith Thompson,
@KeithThompson: Bei dieser Frage und dieser Antwort handelt es sich nicht um Funktionsdefinitionen, sondern um Vordeklarationen.
Ruakh
3
@ruakh: Eine variable Funktion muss mithilfe der Syntax deklariert und definiert werden ..., um undefiniertes Verhalten zu vermeiden.
Keith Thompson