2014-07-11 15 views
5

für einen Tippfehler, lasse ich die a drin. Als ich zu kompilieren ging, berichtete der Compiler:Sollte int a, f() {} kompilieren?

missing a ',' between declaration of 'a' and 'f'

Code:

int a 
f(void) 
{ 
} 

und war sehr surpresing, da ich noch nie so eine beliebige Fehlermeldung bekommen habe, und ich wusste nicht, konnte ich setzen ein Komma gibt und es nur gut zusammengestellt (in mehr als einem Compiler, den ich getestet):

int a, 
f(void) 
{ 
} 

aber natürlich war es nicht meine Absicht, aber int f(void){} statt. Ich gebe einen Versuch in einem anderen Compiler, aber es hat nicht funktioniert und berichtet einen Syntaxfehler wie folgt aus (in Klirren):

error: expected ';' after top level declarator.

Meine Frage ist: was ist richtig? es sollte oder sollte nicht kompilieren? Was sagt der Standard über dieses Verhalten?

Ich werde es nicht verwenden, da es ein bisschen hässlich ist, Variable und Funktionen durch Komma getrennt zu setzen (genau wie es für einen Funktionsprototyp ist). Ich bin nur Neugierig.

EDIT: hinzugefügt void in Funktionsparameter. Eigentlich wollte ich eine Funktion mit leeren Parametern schreiben

+2

Die früheren _seems_ gültig C89, und die letztere ungültig. Für C99 bin ich mir ziemlich sicher, beide sind ungültig (und gcc weigert sich, mit '-std = c99 -pedantic' zu kompilieren). 'int a, f();' (wobei letzteres eine Funktionsdeklaration ist (Funktion, die eine unbestimmte Anzahl von Argumenten entgegennimmt, die 'int' zurückgibt) ohne Definition) wäre jedoch gültig C99. Welchen Standard interessieren Sie? – mafso

+0

Gut zu wissen, werde ich meinen Kommentar entfernen, wie es wirklich nicht mehr als Ihre sagen, aber irgendwie in der Neu-Lesung sagten Sie es sauberer als ich. –

+0

entfernt meins zu – Jack

Antwort

3

Nein, es nicht

Sie benötigen

int a; 
void f(void) 
{ 
} 

die Hohlräume sind nicht der wichtigste Teil in diesem Moment in der Zeit zusammenstellen soll. Der wichtigste Teil ist, dass Sie kein Semikolon nach einem.

Wenn Sie nicht setzen ein Semikolon nach int a die Compiler halten in den nächsten Zeilen als Teil der int Erklärung zu lesen, so dass er nicht erkennen, dass Sie zwei Dinge haben man wollte, sondern eine sehr seltsame Sache, wie

int a f() { } 

Durch das Hinzufügen eines Kommas haben Sie das Problem immer noch nicht behoben. denn wäre eine gültige Möglichkeit, eine Liste von ganzen Zahlen

int a, b; 

gültig ist, während

int a, f() { } 

ist nicht zu erklären, weil f() { } für eine ganze Zahl kein gültiger Name ist ein Komma eine Liste zeigt an, welche. Solche Zeichen mögen an anderen Stellen gültig sein, aber die vorangehende a, verhindert, dass sie auch dort gültig ist. Die Kombination von dem, was gemeint war, zwei Linien zu sein, verhindert, dass es gültig C.

Aber durch ein Semikolon, jetzt erhalten Sie zwei vernünftige Dinge in C.

int a; 
f() { } 

ich, dass jede Funktion, die Sie empfehlen, Schreiben hat einen Rückgabewert, auch wenn nichts zurückgegeben wird.

int a; 
void f() { } 

und wieder ist es eine sehr gute Praxis, um explizit anzuzeigen, dass die Funktion keine Parameter übernehmen, so

int a; 
void f(void) { } 

, die

entspricht
int a; 
void f(void) 
{ 
} 
+0

Ist dies 'C89' Funktionsdefinition? –

+0

C99 erlaubt keine leere Deklaration im Dateibereich (wie in Ihren beiden vorletzten Beispielen, dem '' 'nach dem schließenden'} 'von' f's Funktionskörper). Und Sie sprechen über _declarations_, keine Anweisungen (es gibt keine Anweisungen im Dateibereich). – mafso

+0

@FiddlingBits: 'void f() {}' ist eine gültige Funktionsdefinition in C89/C90, in C99 und in C11. In allen drei Sprachversionen wird 'void f (void) {}' bevorzugt. (Das 'void'-Schlüsselwort und die Prototypsyntax wurden in C89 eingeführt.) –

4

Das wäre Sei ein Syntaxfehler. Die Syntax für eine Funktionsdefinition ist

//  int    f()        {} 
declaration-specifiers declarator declaration-list[opt] compound-statement 

Es gibt keinen Raum für a, vor f() (ich dies an einem zufälligen C11 Entwurf zu stützen). Für C89 sieht es ähnlich aus, außer dass declaration-specifiers optional ist (wegen der impliziten-int-Regel).

0

Die Sprache Grammatik erlaubt keine Funktion Definition als Teil einer Erklärung zu erscheinen. Was kann man tun ist, schreiben

int a, f(void); 

weil dies nur eine Erklärung ist für f.


1. Das heißt, es gibt keinen Weg von der Erklärung non-terminal zum Funktion auflösendes nicht-terminale; siehe Anhang A der online C standard