2017-03-28 33 views
6

コンパイラコースのセマンティック分析を行っているときに混乱しました。定数の初期化要素ではありませんか?

#include <stdio.h> 

int a = "abcd"[2]; 

int main() 
{ 
    char b = "abcd"[2]; 

    printf("%d\n%c\n", a, b); 

    return 0; 
} 

GCCは、変数 "a"に対して "error:initializer要素が定数ではありません"と表示します。

なぜですか?

+2

gcc quirkのように見えますが([clang]はかなり満足しています)(https://godbolt.org/g/0CPrpX)、[IntelのICC](https://godbolt.org/g/JGL3nL) )。 –

+1

@PaulRアセンブリを見ると、clangはそれを定数式として扱いません(値はmainの先頭で計算され、変数に格納されます)。だから、グローバルイニシャライザが静的である必要があるという標準の要求をclangが落としたように見えます。 – sepp2k

+0

それはvsで私のためにコンパイルされ、99 c –

答えて

5

C言語では、グローバル変数の初期化子が定数式である必要があります。この背後にある動機は、コンパイラがコンパイル時に式を計算し、計算された値を生成されたオブジェクトファイルに書き込むことができるようにすることです。あなたが例以外は、配列アクセス式やポインタ参照を含んで見ることができるように

  1. An integer constant expression117) shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator .
  2. More latitude is permitted for constant expressions in initializers. Such a constant expression shall be, or evaluate to, one of the following:
    • an arithmetic constant expression,
    • a null pointer constant,
    • an address constant, or
    • an address constant for a complete object type plus or minus an integer constant expression.

The C standardは定数式である何のための特定の規則を提供します。したがって、"abcd"[2]は、標準に従って定数式として修飾されません。

今の標準にも書かれています:

  1. An implementation may accept other forms of constant expressions.

だから、定数式として"abcd"[1]を許可する標準に違反していないだろうが、また許可される保証はありません。

コンパイラで許可するかどうかはあなた次第です。コンパイル時に式を評価できるようにする必要があります(実際には、あなたのisConstantExpressionチェックで別のケースを必要とするため、より多くの作業が可能ですが、許可しないでください)。

0

int a = "abcd" [2];

aはコンパイル時にグローバル変数initilizeですが、実行時に "abcd" [2]が計算されます。

char b = "abcd" [2];

ここで、bはローカル変数で、実行時に "abcd" [2]が計算された後に実行されます。

関連する問題