2009-11-11 4 views
27

私はこのSO questionを見ていて、const intsと#definesを考えて、コンパイラがこれに対処できない理由を実際には理解していないことに気付きました。gccでconst intをcase式として使用できないのはなぜですか?

ことを私は6.8.4.2.3で述べISO-C99の仕様を読んで、なぜ次のコード

const int FOO = 10; 

int main(int argc, char** argv) 
{ 
    switch(argc) 
    { 
     case FOO: { printf("foo\n"); } 
     default: { printf("default\n"); } 
    } 
} 

error: case label does not reduce to an integer constant 

で結果に関して、誰かがいくつかの光を当てることができ各ケースのラベルの表現 は整数定数 となります。 の定数式は同じです スイッチ文は、変換後に同じ の値を持ちます。

私はなぜ大文字小文字の表現が定数でなければならないのか理解していますが、リテラルだけではコンパイラ(gcc 4.2.1)が幸せにならない理由は分かりません。

+0

興味深いことに、gcc-4.3.4でコードが正しくコンパイルされて実行されているようです。http://ideone.com/n1bmIb 編集:Ah ..しかし、C++ではなくC. – GrahamS

答えて

26

定数式は、技術的には値がcaseステートメントの時点でコンパイラによって認識されていますが、const修飾型の値と同じではありません。

別のファイルがextern const int FOOと宣言され、同じように使用しようとするとどうなるか想像してみてください。コンパイラは、別のファイルで定義されているため、FOOが何であったのかわかりません。 の値がの定数であっても、定数の式ではありません。

+2

Ah。 externの例をありがとう。スーパークリア。 – nall

+13

'extern'の例では、何もわかりませんし、何も説明しません。 C++言語では、C言語の場合と同様に 'extern'定数を宣言することもできますが、C++では' const int'オブジェクトを定数式で使用することができます。元の質問に対する唯一の真の答えは、それが歴史的にそのように行われたということです。 Cの初めから、「定数」という用語は文字定数であり、 'const'オブジェクトではありませんでした。どうして?ただの理由。 – AnT

+1

さて、externの例は、コンパイラが扱うことができなかった私が思い付くことのできないものでした。あなたのコメントは貴重です。ありがとう。 – nall

関連する問題