1. ホーム
  2. c

[解決済み] ISO C90では可変長配列は禁止されている

2022-02-11 21:48:25

質問事項

配列のサイズを動的に計算しています。以下のようなものです。

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:

サイズが整数定数でない式である場合 評価されるたびに、その値を持たなければならない。 0より大きい値です。

ということで、サイズ制限型変数の再宣言をしてみました。

void foo(const size_t limit)

しかし、私の場合は警告が出続けています。これはGCCのバグなのでしょうか?

解決方法は?

const -変数を修飾しても、コンパイル時の定数にはなりません。 整数定数式 C99で可変長配列が導入される以前は、配列のサイズはコンパイル時の定数である必要がありました。

というのは、むしろ当然のことである。 const -特に、関数が呼び出されるまで初期化されない関数のパラメータの場合、変数を修飾しても、コンパイル時の定数にはなりません。

あなたの問題に対する解決策は、以下のようになりますね。

  • でC99としてコンパイルします。 -std=c99 または -std=gnu99
  • でバッファを確保します。 malloc()
  • 使用 alloca() これは、C90 で可変長配列に最も近い方法です。
  • は、常に使用される最大バッファサイズを選択し、与えられた limit 引数がオーバーフローする

余談ですが、C99 では可変長の配列が認められていますが、静的な保存期間を持つ整数型変数の値を、静的な保存期間を持つ配列のサイズとして使用することは、以下の点に関係なく違法です。 const -という修飾があります。整数型変数が同じ翻訳単位で初期化されていれば、原理的にこれを妨げるものはありませんが、定義が見える変数と定義が別の翻訳単位にある変数を特別扱いする必要があります。また、仮定義を無効にするか、翻訳単位全体をパースするまで仮定義の変数の初期化値が分からないため、複数のコンパイルパスを必要とすることになるでしょう。