8

私はC ++に比較的慣れていません。最初から、次のようなことはできないと教えられてきました。

int x;
cin >> x;
int array[x];

代わりに、動的メモリを使用する必要があります。ただし、最近、上記がコンパイルされることを発見しました(ただし、ISO C ++で禁止されているというペダンティックな警告が表示されます)。標準で許可されていない場合、それを行うのは明らかに悪い考えであることは知っていますが、以前はこれが可能であることさえ知りませんでした。

私の質問は、標準で許可されていない場合、動的に割り当てられない可変長配列を g++ が許可するのはなぜですか? また、コンパイラがそれを行うことが可能である場合、なぜそれが標準にないのですか?

4

4 に答える 4

19

可変長配列 (VLA) のサポートが C99 の C 言語に追加されました。

それらのサポートは (C99 をサポートするために) gcc に存在するため、それらのサポートを g++ に追加するのは比較的簡単だったと思われます。

とはいえ、これは実装固有の言語拡張であり、コードを移植可能にしたい場合は、実装固有の拡張を使用することはお勧めできません。

于 2010-04-09T19:50:41.460 に答える
5

C99でサポートされているためです。なぜそれが C++ 標準に含まれていないのか、私にはよくわかりません。ただし、(注意しないと) スタック オーバーフローが発生しやすいため (通常はallocaに基づいており、それ自体が非標準であるため)、思ったほど有用ではありません。もう 1 つの間違いは、動的配列へのポインタを返すことです。これはすぐに範囲外になります。

于 2010-04-09T19:50:41.370 に答える
3

多くのコンパイラは、標準を取り入れて拡張しています。2 つの基本的な理由があります。

  1. 悪意のあるコンパイラ作成者は、おそらく、コンパイラから離れにくくすることで寿命が延びると考えています。
  2. 親切なコンパイラ ライターはおそらく、ほとんどまたはまったくコストをかけずに、より多くのオプションを提供することは良いことだと考えています。
于 2010-04-09T19:52:50.490 に答える
1

要件には制限がありますが、それらが C にあることに関係しなければならない理由はすべて正しいです。あなたの例は、Cで必要とされるものよりも柔軟なサポートを示すかもしれません(cinではなくscanfを使用して実装した場合は、.cファイルに入れ、gccを使用します)。

これはほとんど alloca (allocate auto) への暗黙的な呼び出しであり、スタック ポインターを減らし (スタック サイズを増やします)、新しいスタック ポインターを、割り当てられたメモリへのポインターとして使用される別のレジスターにコピーします。

違いは、アロカで作成されたオブジェクトではコンストラクタとデストラクタが呼び出されないことです。

于 2010-04-09T20:07:01.627 に答える