6

配列のサイズを動的に計算しています。何かのようなもの:

void foo(size_t limit)
{
  char buffer[limit * 14 + 1];
}

しかし、GCCコンパイラだけが言う:

error: ISO C90 forbids variable length array ‘buffer’

SOで検索すると、この答えが見つかりました:

C99 §6.7.5.2:

サイズが整数定数式ではない式の場合... ...評価されるたびに、ゼロより大きい値を持つ必要があります。

そこで、サイズ制限型変数を次のように再宣言しました。

void foo(const size_t limit)

しかし、それは私に警告を与え続けています。これは GCC のバグですか?

4

6 に答える 6

12

const-変数を修飾してもコンパイル時定数にはなりません(整数定数式の定義についてはC996.6§6を参照)。C99で可変長配列を導入する前は、配列サイズをコンパイル時にする必要がありました。定数。

const特に関数が呼び出されるまで初期化されない関数パラメーターの場合、-qualify変数がコンパイル時定数にならないことはかなり明白です。

私はあなたの問題に対する次の解決策を見ます:

  • -std=c99またはを介してコードをC99としてコンパイルします-std=gnu99
  • を介してバッファを割り当てますmalloc()
  • 可能な場合は使用しalloca()ます。これは、C90で可変長配列に到達できる最も近い配列です。
  • 常に使用される最大バッファサイズを選択し、指定されたlimit引数がオーバーフローした場合は失敗します

ちなみに、C99では可変長配列が許可されていますが、const-qualificationに関係なく、静的保存期間のある整数変数の値を静的保存期間のある配列のサイズとして使用することは違法です。これを妨げるものはありません。原則として、整数変数が同じ翻訳単位で初期化される場合、定義が別の翻訳単位にある変数とは明確に定義された特殊なケースの変数を使用する必要があり、暫定的な定義を許可しないか、次のように複数のコンパイルパスが必要になります。暫定的に定義された変数の初期化値は、変換単位全体が解析されるまでわかりません。

于 2012-04-19T20:08:00.993 に答える
6

constC では定数を導入しませんが、読み取り専用の変数を導入します。

#define SIZE 16
char bla[SIZE];   // not a variable length array, SIZE is a constant

しかし

const int size = 16;
char bla[size];   // C99 variable length array, size is a constant
于 2012-04-19T18:21:18.567 に答える
3

C90では可変長配列は使用できません。ただし、c99-gccコンパイラを使用してこれを機能させることができます。

あなたはコンパイルしてc90-gccいますが、C99仕様を見ています。

于 2012-04-19T18:19:33.433 に答える
2

いいえ、バグではありません。C90ではVLAを使用できません。宣言したとき

const size_t limit

それは定数式ではありません。定数式は、リテラル値のようなものになります666

この点で、CはC++とは大幅に異なることに注意してください。このような定数でも

const int i = 666;

#defineはCの定数式ではありません。これが、定数値が通常Cで宣言される主な理由です。

于 2012-04-19T18:19:46.813 に答える
0

あなたの質問に書かれているように、これはC90ではなくC99からのものです。可変長配列を使用できるようにするには、C99に対してコンパイルする必要があります。

于 2012-04-19T18:19:53.287 に答える
0

修飾変数は、標準的な意味でのconst整数定数式ではありません。これは、リテラル定数、列挙定数、sizeofまたはこれらで構成される何らかの式である必要があります。

可能であれば、C99 に切り替えてください。gcc オプションは-std=c99(gnu 拡張が必要な​​場合は gnu99) です。

于 2012-04-19T18:21:36.617 に答える