
Destruktor
Betrachten Sie das folgende Programm (siehe Live-Demo hier).
#include <stdio.h>
int main(void)
{
int ; // Missing variable name
puts("Surprise");
}
Mein Compiler, gcc 4.8.1, gibt die folgende Warnung aus:
[Warning] nutzloser Typname in leerer Deklaration [enabled by default]
Warum lässt es sich gut kompilieren? Sollte ich nicht einen Compiler-Fehler erhalten? g++ 4.8.1 gibt den folgenden Fehler aus, wenn ich es als C++-Programm kompiliere:
[Error] Deklaration deklariert nichts [-fpermissive]

n. 1.8e9-wo-ist-meine-Aktie m.
Die C-Norm sagt
Eine andere Deklaration als eine static_assert-Deklaration muss mindestens einen Deklarator (anders als die Parameter einer Funktion oder die Mitglieder einer Struktur oder Vereinigung), ein Tag oder die Mitglieder einer Enumeration deklarieren.
sagt C++
In einer einfachen Deklaration kann die optionale Init-Declarator-Liste nur weggelassen werden, wenn eine Klasse (Klausel 9) oder eine Aufzählung deklariert wird.
Ein Verstoß dagegen in beiden Sprachen erfordert eine Diagnose. Die Standards sprechen nicht über Compilerfehler oder Warnungen. Eine Warnung ist eine Diagnose.

Ameise
Ihr Code ist sowohl in C als auch in C++ illegal (dh fehlerhaft, schlecht geformt, gegen Einschränkungen verstoßend). Der Grund, warum Sie in einer Sprache eine “Warnung” und in einer anderen einen “Fehler” erhalten, ist nur eine Eigenart Ihres Compilers und Ihres Compiler-Setups. Schließlich unterscheiden beide Sprachen formal nicht wirklich zwischen „Warnungen“ und „Fehlern“. GCC ist unter seinen Standardeinstellungen im C-Modus freizügiger (hauptsächlich aus historischen Gründen).
Verwenden -pedantic-errors
in GCC, und Sie erhalten auch einen “Fehler” im C-Code. (Beachten Sie, dass -pedantic-errors
wandelt nicht einfach blind alle “Warnungen” in “Fehler” um. Es wird versucht, nur tatsächliche zu melden Beschränkungsverletzungen als “Fehler”.)

Yu Hao
Die Syntax der Deklaration ist definiert als (Weglassen Init-Declarator-Liste und Init-Deklarator):
C11 6.7 Erklärungen
declaration:
declaration-specifiers init-declarator-list opt ;
static_assert-declaration
declaration-specifiers:
storage-class-specifier declaration-specifiers opt
type-specifier declaration-specifiers opt
type-qualifier declaration-specifiers opt
function-specifier declaration-specifiers opt
alignment-specifier declaration-specifiers opt
Beachten Sie, dass Deklarationsbezeichner ist rekursiv definiert, aber jeweils mit einem opt gibt an, dass es optional ist.
Auch die folgende Klausel 6 besagt:
Die Deklarationsbezeichner bestehen aus einer Folge von Bezeichnern, die die Verknüpfung, die Speicherdauer und einen Teil des Typs der Entitäten angeben, die die Deklaratoren bezeichnen. Die initdeclarator-list ist eine durch Kommas getrennte Folge von Deklaratoren, von denen jeder zusätzliche Typinformationen oder einen Initialisierer oder beides haben kann. Die Deklaratoren enthalten die Bezeichner (wenn überhaupt) deklariert werden.
Beachte die Wörter wenn überhaupt.
10159100cookie-checkWarum lässt sich `int ;` in C gut kompilieren, aber nicht in C++?yes
@Nawaz: Wird es explizit durch die Sprachspezifikation gesagt?
– Destruktor
22. Oktober 2015 um 4:47 Uhr
Im C++-Standard heißt es explizit: “[dcl.dcl]/5 In einem einfache Erklärungdie Wahl Init-Declarator-Liste kann nur weggelassen werden, wenn eine Klasse (Abschnitt 9) oder eine Aufzählung (7.2) deklariert wird, das heißt, wenn die decl-spezifizierer-seq enthält entweder a Klassenbezeichnerein ausgearbeiteter Typbezeichner mit einer Klassenschlüssel (9.1) oder ein Enum-Spezifizierer.” Ich bin mit dem C-Standard nicht gut genug vertraut, um Kapitel und Verse zu zitieren.
– Igor Tandetnik
22. Oktober 2015 um 4:54 Uhr
“Erzeugt eine Warnung” ist nicht “kompiliert gut”.
– n. 1.8e9-wo-ist-meine-Aktie m.
22. Oktober 2015 um 5:13 Uhr
Nun, Sie können mehrere Locals gleichzeitig definieren (
int a, b, c;
), Rechts?int ;
sieht nur aus wie ein Sonderfall derselben Sache, mit 0 deklarierten Einheimischen: D– Luan
22. Oktober 2015 um 12:31 Uhr
Neu kompilieren mit
-Werror
– David Konrad
22. Oktober 2015 um 23:07 Uhr