web-dev-qa-db-ja.com

`int;`がCで正常にコンパイルされるのにC ++ではコンパイルされないのはなぜですか?

次のプログラムを検討してください(ライブデモ here を参照)。

#include <stdio.h>
int main(void)
{
      int ;  // Missing variable name
      puts("Surprise");
}

私のコンパイラ、gcc 4.8.1は以下の警告を出します:

[警告]空の宣言に不要な型名があります[デフォルトで有効]

うまくコンパイルできるのはなぜですか?コンパイラエラーは発生しませんか? C++プログラムとしてコンパイルすると、g ++ 4.8.1で次のエラーが発生します。

[エラー]宣言は何も宣言していません[-fpermissive]

57
Destructor

C標準は言う

Static_assert宣言以外の宣言では、少なくとも宣言子(関数のパラメーター、構造体または共用体のメンバー以外)、タグ、または列挙型のメンバーを宣言する必要があります。

C++は言う

単純な宣言では、オプションのinit-declarator-listは、クラス(条項9)または列挙を宣言する場合にのみ省略できます。

どちらの言語でもこれに違反するには、診断が必要です。標準では、コンパイラのエラーや警告については触れていません。警告は診断です。

48
n.m.

あなたのコードは、CとC++の両方で違法です(つまり、エラーがあり、形式が正しくなく、制約違反です)。ある言語で「警告」が表示され、別の言語で「エラー」が表示される理由は、コンパイラとコンパイラの設定の癖にすぎません。結局のところ、どちらの言語も「警告」と「エラー」を正式に区別するものではありません。デフォルトの設定でのGCCは、Cモードではたまたま許容範囲が広いです(主に歴史的な理由による)。

使用する -pedantic-errors GCCでは、Cコードでも「エラー」が表示されます。 (ご了承ください -pedantic-errorsは単にすべての「警告」を「エラー」に盲目的に変えるだけではありません。実際の制約違反のみを「エラー」として報告しようとします。)

34
AnT

宣言の構文は、(省略init-declarator-listおよびinit-declarator):

C11 6.7宣言

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

declaration-specifiersは再帰的に定義されていますが、それぞれoptが付いていることはオプションであることを示しています。

また、次の第6項には、

宣言指定子は、リンケージ、ストレージ期間、および宣言子が示すエンティティーのタイプの一部を示す一連の指定子で構成されます。 initdeclarator-listは、コンマで区切られた宣言子のシーケンスであり、それぞれに追加の型情報、初期化子、またはその両方が含まれる場合があります。宣言子には識別子(存在する場合)が宣言されています。

単語がある場合は注意してください

18
Yu Hao