2013-07-09 15 views
5

私はC99でプログラミングしており、コードの一部で可変長配列を使用しています。私はC89で長さゼロの配列は許可されていないことを知っていますが、私はC99と可変長の配列が不明です。可変長配列の長さはゼロですか?

つまり、次のような明確な動作がありますか?

int main() 
{ 
    int i = 0; 
    char array[i]; 
    return 0; 
} 
+0

「i」はコンパイル時定数ではないので、コンパイルすべきではありません。 – Jashaszun

+1

それをコンパイルしてみてください。 gccが出て、パンチして、あなたを撃ち、あなたの車を盗むでしょう。 –

+4

[男...これはC99です... C89ではありません。](http://ideone.com/NKtfJD) – Cornstalks

答えて

13

いいえ、長さゼロの配列は、明示的に彼らは(あなたのコードサンプルのように)実行時のサイズ値によってVLAとして作成されている場合でも、C言語で禁止されています。

6.7.5.2アレイは

を宣言子...

サイズは、整数定数 式ではない式である場合:それは関数で宣言で発生した場合プロトタイプスコープ は、*で置き換えられたかのように扱われます。 それ以外の場合は、 と評価されるたびに0より大きい値が設定されます。

+0

Oooo、yay、標準からの引用。私はそれらが好きです。 +1! – Cornstalks

2

静的に型指定された配列は、定数でない固定サイズの定数でなければならず、可変長配列のサイズはゼロでないと評価されなければなりません。 C11 6.7.6.2/5:

それ【サイズ発現】なお、ただしゼロより大きい

値を有するものと評価されるたびに、C99及びC11は、可撓性アレイの概念を持っています構造体のメンバ:C11から

struct foo 
{ 
    int a; 
    int data[]; 
}; 

、6.7.21/18:

特殊なケースとして、複数の名前付きメンバを持つ構造体の最後の要素には、不完全な配列型の があります。これはフレキシブルアレイメンバと呼ばれます。ほとんどの場合、 フレキシブルな配列メンバは無視されます。特に、構造のサイズは、あたかも のフレキシブルな配列メンバが省略されているかのようになります。ただし、省略されていることを意味する よりも多くの末尾の埋め込みがある場合があります。しかし、.(または->)演算子が、フレキシブルな配列メンバーを持つ構造体への (へのポインタ)の左オペランドと、 という右オペランド名を持つ場合、そのメンバーが最長配列に置き換えられたかのように動作します構造体をアクセスされるオブジェクトよりも大きくしない(同じ 要素タイプを持つ)

+0

フレキシブルアレイメンバーのご注意ありがとうございます。標準からの引用は本当に便利でした! – Cornstalks

1

標準長のCでは、長さがゼロの配列は使用できません(C99またはC11以外)。しかし、gccはそれを可能にする拡張機能を提供しています。 http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

struct line { 
    int length; 
    char contents[0]; 
}; 

struct line *thisline = (struct line *) 
    malloc (sizeof (struct line) + this_length); 
thisline->length = this_length; 
関連する問題