2012-12-28 30 views
7

可能性の重複:
Variably modified array at file scopeCでの可変長配列(VLA)とC++

私は明確にする必要がVLAとその動作についてのいくつかの概念を持っています。

int main(int argc, char **argv) 
{ 
    // function 'main' scope 
    int size = 100; 
    int array[size]; 
    return 0; 
} 

しかし、それがグローバルスコープで禁止されています:

アフィクC99ので、それがローカルスコープにVLAを宣言することが可能です

const int global_size = 100; 
int global_array[global_size]; // forbidden in C99, allowed in C++ 

int main(int argc, char **argv) 
{ 
    int local_size = 100; 
    int local_array[local_size]; 
    return 0; 
} 

const修飾子ので、上記のコードは、C99でV​​LAを宣言しますコンパイル時の値は作成されません。 C++では、global_sizeはコンパイル時の値なので、global_arrayはVLAにはなりません。

私が知る必要があるのは、私の推論は正しいのですか?私が記述した動作は正しいですか?

また知りたいことは:なぜグローバルスコープ内のVLAは許可されていないのですか? CとC++の両方で禁止されていますか?グローバルスコープとローカルスコープの配列の動作が異なる理由は何ですか?

+5

グローバルVLAが許可されているとします。彼らの(可変)サイズはいつ実際に定義されていますか? – cnicutar

+0

@cnicutarよく...他のスコープと同様に、実行時にはすべてのVLAと同様です。私はこれが答えではないことを知っていますが、私はWHYを知りたいのです。 –

+1

http://stackoverflow.com/a/5052083/174605 – coelhudo

答えて

5

はい、あなたの推論は正しいです。つまり、これらの異なる形式の配列宣言と定義は、CとC++によってどのように表示されますか。

すでに述べたように、グローバルなスコープ内で真の可変長(非const)のVLAは理にかなっていません。長さ式が異なるコンパイル単位のオブジェクトを参照する場合など、評価順序はどのようになりますか? C++にはVLAはありませんが、ファイルスコープでオブジェクトを動的に初期化します。そして、評価の順序に頼らなければならない場合は、既にこれはあなたに大きな痛みを与えています。

これは、許可されていないconst修飾オブジェクトを含む長さ式に関するCの小さなギャップを残します。これは、そのようなオブジェクトがC標準によって「整数定数式」とみなされないという事実に由来します。これは将来のバージョンではおそらく変化する可能性がありますが、これまでC委員会はこのようなことを許す必要はないと指摘しました。enum定数がC言語でその役割を果たす定数です。その唯一の制限はint C、size_tも持っているといいですね。

+0

最後に誰かが質問全体を読んだことが分かります!私は他の事実に集中しているので、この質問は[重複](http://stackoverflow.com/questions/1712592/variably-modified-array-at-file-scope)ではありません。ほとんどすべての私の質問に答えるための説明とありがとう、ありがとう。 –

1

禁止されていると許可されていないという違いがあります。 ;-)

VLA機能は、ヒープ割り当てにmallocを使用しないように、ローカル配列のスタックスペースを使用できるように設計されています。これは主に速度の最適化です。

ここで、機能の外にVLAを使用したいとします。どうして?プログラムの開始時に1回のmalloc呼び出しを回避することで、スピードをあげることはあまりありません。静的なライフタイムを持つ変数にはどのようなスタックスペースを使用することになっていますか?

3

私は基本的な理由は、グローバル変数はリンケージを持っていると思う、そのサイズはコンパイル時に知られている必要があります。そうでない場合、どのようにプログラムをリンクすることができますか?

ローカル変数にはリンケージがなく、VLAはスタックに割り当てられます。このVLAは、プログラムの実行中に動的に増加します。

2

C++はVLAをサポートしていません。 2番目のコードスニペットがC++で動作する理由は、constキーワードがC++でコンパイル時定数を作成するためです。 Cではそうではありません。

C99では、size変数の宣言方法に関係なく、ブロックスコープ、期間外のVLAはサポートされません。 C2011は、VLAサポートをオプションにします。

+0

はい、私は 'const'キーワードがC++でコンパイル時定数を作成することを知っていますが、Cではそうではありません。 –

1

ので、グローバルVLAのために、課題(テーマに多くのバリエーションがある)の一つがここに示すことができる。

int size; 
int a; 
int v[size]; 
int b; 

.... 別のファイルに:

extern int a; 
extern int b; 

リンカーは、リンク時にaとbeが互いの関係にあるかどうかを知る必要があります。そうしないと、ロード時にそれらを正しく修正できません。