14

次のコードは、gcc 4.8 および Clang 3.2 でコンパイルされます。

int main()
{
  int size = 10;
  int arr[size];
}

C++ 標準の 8.3.4/1 は、配列のサイズは整数定数式でなければならないと述べていますが、そうでsizeはないようです。これは両方のコンパイラのバグですか、それとも何か不足していますか?

最新の VC++ CTP は、次の興味深いメッセージでコードを拒否します。

error C2466: cannot allocate an array of constant size 0

size興味深いのは、それがゼロであるとどのように考えているかです。しかし、少なくともコードは拒否されます。gcc と Clang は同じことをすべきではありませんか?

4

1 に答える 1

34

これは、C99の機能である可変長配列またはVLAですが、 gccclangはC++の拡張機能としてサポートしていますが、Visual Studioはサポートしていません。この場合、標準に準拠しており、技術的に正しいです。拡張機能が悪いと言うわけではありませんが、Linux カーネルは多くの gcc 拡張機能に依存しているため、特定のコンテキストで役立つ場合があります。Visual Studio

-pedantic両方のフラグを追加するgccclang、これについて警告が表示されます。たとえば、次のように表示されgccます ( see it live ):

warning: ISO C++ forbids variable length array 'arr' [-Wvla]
  int arr[size];
              ^

-pedantic-errorsフラグを使用すると、これがエラーになります。拡張機能の詳細については、これらのドキュメントGCC でサポートされている言語標準clang 言語互換性セクションを参照してください。

アップデート

ドラフト C++ 標準では、セクション定数式の段落3で整数定数式とは何かをカバーしており、次のように述べています。5.19

整数定数式は、暗黙的に prvalue に変換された整数またはスコープなし列挙型の式であり、変換された式はコア定数式です。[...]

すべての可能性が何であるかは、これを読んでも直感的には明らかではありませんが、Boost の整数定数式のコーディング ガイドラインはその点で優れています。

この場合、constを使用sizeしてリテラルで初期化しているため、それを整数定数式にするのに十分であり( [expr.const]p2.9.1を参照)、コードを標準のC++に戻します。

const int size = 10;

constexprを使用しても機能します。

constexpr int size = 10;

との違いconstexprconst読むとおそらく役立つでしょう。

参考までに、C99 ドラフト標準8.3.4のパラグラフ1に相当するセクションは、セクションArray declaratorsパラグラフ4であり、次のように記述されています (強調鉱山):6.7.5.2

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

于 2014-01-22T03:54:29.893 に答える