8

私はこれらを見てきましたが、私の質問に答えていません:

可変サイズのオブジェクトは初期化できない可能性があります

C コンパイル エラー:「可変サイズ オブジェクトが初期化されていない可能性があります」

エラー: 可変サイズ オブジェクトが初期化されていない可能性があります。しかし、なぜ?


私はかなりポータブルなcコードを書こうとしています:

int main () 
{
    const int foo=13;
    int bar[foo]={0};
    return 0;
}


次のいずれかを使用してコードとしてコンパイル すると、variable-sized object may not be initializedエラーが発生します。c

  • gcc 4.3.4
  • arm-linux-gnueabi-gcc 4.4.5

そして、VS2008のようcコンパイルすると、少し異なりますerror C2057: expected constant expression


ここで、cコード コンパイラがconst int foo=13;真に一定であることを認識していないことを理解しています。たとえば、

void a(int fool) 
{    
    const int foo=fool;
    int bar[foo]={0};
}


また、gcc コンパイラとは異なり、 VS2008コンパイラにはC99 可変長配列の概念がないことも認識しています。そして、その MS は明らかに将来のサポートについて言及していません。


それでも、gccコンパイラまたはMScppコンパイラを使用したコードのコンパイルは、まったく異なります。


また、 gccコード コンパイラに関して私が理解していないことは次のとおりです。 c


(注: この最後のケースでは、MS cコードのコンパイルは失敗します。一貫して と同様ですint bar[foo]={0};)

4

3 に答える 3

13

C99 §6.7.8初期化はこれを言います:

初期化するエンティティの型は、サイズが不明な配列または可変長配列型ではないオブジェクト型でなければなりません。

したがって、初期化は無効です C.

が VLAtype a[size]ならない唯一の方法はsize整数定数式になることです (§6.7.5.2)。そこにあるのは整数定数式ではないため、VLA があります。

サイズが存在しない場合、配列型は不完全型です。サイズが式ではなく * の場合、配列型は未指定のサイズの可変長配列型であり、関数プロトタイプ スコープの宣言でのみ使用できますが、そのような配列は完全な型です。サイズが整数定数式で、要素の型に既知の定数サイズがある場合、配列型は可変長配列型ではありません。それ以外の場合、配列タイプは可変長配列タイプです。

パート §6.6/6定数式では、次のように定義されています。

整数定数式は整数型を持ち、整数定数、列挙定数、文字定数、結果が整数定数である sizeof 式、およびキャストの即値オペランドである浮動定数であるオペランドのみを持つ必要があります。整数定数式のキャスト演算子は、オペランドの一部として sizeof 演算子を除いて、算術型のみを整数型に変換します。

于 2012-04-12T18:39:29.730 に答える
1

実際、私のgcc(バージョン4.4.4)の場合、最後の例

int main()
{
    const int foo=13;  
    int bar[foo+1]={0}; //wtF?
    return 0;
}

また、期待どおりにコンパイルされません。ツールチェーンを再確認し (既存の '.o' をどこかに再リンクしていないことを確認するため)、もう一度やり直してください。

それが実際に機能することがわかった場合、これが私のgcc -v出力です。おそらく、構成の違いを検出でき、それがいくらかの光を当てるかもしれません.

Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.4 20100630 (Red Hat 4.4.4-10) (GCC) 
于 2012-04-12T18:34:21.020 に答える
-1

Matt が既に標準を引用しているconstように、整数変数に適用される修飾子は整数定数式としてカウントされません。なぜだろう?整数定数と同じくらい無害に見えます!

これは絶対にないからかもしれません。ポインターを介してそれらの値を変更する可能性があり、コンパイラーがそのような割り当てをキャッチした場合、警告をスローするだけで、値の変更を実際に防ぐことはできません。constconstsconst

PS: ideone.comなどのオンライン コンパイラは信用しないでください。非常に単純な C プログラムで発生するばかげたランタイム エラーを次に示します。

于 2012-04-12T18:47:58.477 に答える