私は C99 でプログラミングしており、コードの一部で可変長配列を使用しています。C89 では長さゼロの配列が許可されていないことは知っていますが、C99 と可変長配列についてはわかりません。
要するに、次の明確に定義された動作はありますか?
int main()
{
int i = 0;
char array[i];
return 0;
}
いいえ、長さゼロの配列は、実行時のサイズ値を介して VLA として作成された場合でも (コード サンプルのように)、C 言語によって明示的に禁止されています。
6.7.5.2 配列宣言子
...
5 size が整数定数式ではない式の場合: 関数プロトタイプ スコープでの宣言にある場合は、* に置き換えられたものとして扱われます。それ以外の場合は、評価されるたびにゼロより大きい値になります。
C では、長さゼロの配列は許可されていません。静的に型指定された配列は、定数式であるゼロ以外の固定サイズでなければならず、可変長配列はゼロ以外と評価されるサイズでなければなりません。C11 6.7.6.2/5:
[サイズ式] が評価されるたびに、ゼロより大きい値を持つ必要があります。
ただし、C99 と C11 には、構造体の柔軟な配列メンバーの概念があります。
struct foo
{
int a;
int data[];
};
C11、6.7.21/18 から:
特殊なケースとして、複数の名前付きメンバーを持つ構造体の最後の要素は、不完全な配列型を持つ場合があります。これはフレキシブル配列メンバーと呼ばれます。ほとんどの場合、柔軟な配列メンバーは無視されます。特に、構造体のサイズは、柔軟な配列メンバーが省略されている場合と同じですが、省略が意味するよりも多くの末尾のパディングがある場合があります。ただし、
.
(or->
) 演算子の左側のオペランドが柔軟な配列メンバーを持つ構造体 (へのポインター) であり、右側のオペランドがそのメンバーの名前である場合、そのメンバーが最長の配列 (同じ配列) に置き換えられたかのように動作します。アクセスされるオブジェクトよりも構造を大きくしない要素タイプ)。
長さゼロの配列は、標準 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;