(背景:CおよびC ++コンパイラの実装経験があります。)
C99の可変長配列は、基本的には失敗でした。VLAをサポートするために、C99は常識に基づいて次の譲歩をしなければなりませんでした。
sizeof x
常にコンパイル時定数ではなくなりました。コンパイラはsizeof
、実行時に式を評価するためのコードを生成する必要がある場合があります。
2次元VLA(int A[x][y]
)を許可するには、2DVLAをパラメーターとして受け取る関数を宣言するための新しい構文が必要でしたvoid foo(int n, int A[][*])
。
C ++の世界ではそれほど重要ではありませんが、組み込みシステムプログラマーのCのターゲットオーディエンスにとって非常に重要です。VLAを宣言することは、スタックの任意の大きなチャンクを切り刻むことを意味します。これは、スタックオーバーフローとクラッシュが保証されています。(宣言するときはいつでもint A[n]
、2GBのスタックに余裕があることを暗黙的に主張しています。結局のところ、「n
ここでは間違いなく1000未満」であることがわかっている場合は、宣言するだけですint A[1000]
。32ビット整数n
をに置き換えること1000
は承認です。プログラムの動作がどうあるべきかわからないこと。)
では、C++について話しましょう。C ++では、「型システム」と「値システム」の間にC89と同じように強い違いがありますが、Cにはない方法で実際に依存し始めています。例えば:
template<typename T> struct S { ... };
int A[n];
S<decltype(A)> s; // equivalently, S<int[n]> s;
コンパイル時定数でなけれn
ば(つまり、A
可変的に変更されたタイプの場合)、いったい何のタイプになるS
でしょうか?S
のタイプも実行時にのみ決定されますか?
これはどうですか:
template<typename T> bool myfunc(T& t1, T& t2) { ... };
int A1[n1], A2[n2];
myfunc(A1, A2);
コンパイラは、のインスタンス化のためのコードを生成する必要がありますmyfunc
。そのコードはどのように見えるべきですか?A1
コンパイル時にタイプがわからない場合、どうすればそのコードを静的に生成できますか?
n1 != n2
さらに悪いことに、実行時にそれが判明した場合はどうなります!std::is_same<decltype(A1), decltype(A2)>()
か?その場合、テンプレート型の推定は失敗するはずなので、への呼び出しmyfunc
はコンパイルすらすべきではありません!実行時にその動作をどのようにエミュレートできますか?
基本的に、C ++は、テンプレートコードの生成、関数の評価など、コンパイル時にますます多くの決定をプッシュする方向に進んでいます。その間、C99は従来のコンパイル時の決定(例)をランタイムconstexpr
にプッシュするのに忙しかった。これを念頭に置いて、 C99スタイルのVLAをC ++に統合しようと努力することは本当に意味がありますか?sizeof
他のすべての回答者がすでに指摘しているように、C ++は、「必要なRAMの量がわからない」という考えを本当に伝えたい場合に、多くのヒープ割り当てメカニズム(std::unique_ptr<int[]> A = new int[n];
または明白なメカニズム)を提供します。std::vector<int> A(n);
また、C ++は、必要なRAMの量がRAMの量よりも多いという避けられない状況に対処するための優れた例外処理モデルを提供します。しかし、うまくいけば、この回答が、C99スタイルのVLAがC ++に適していない理由、そして実際にはC99に適していない理由についての良いアイデアを提供します。;)
このトピックの詳細については、VLAに関するBjarneStroustrupの2013年10月の論文であるN3810「AlternativesforArrayExtensions」を参照してください。BjarneのPOVは私のものとは大きく異なります。N3810は、物事に適したC ++風の構文を見つけることに重点を置き、C ++でraw配列を使用しないようにすることに重点を置いていますが、メタプログラミングと型システムへの影響に重点を置いています。彼がメタプログラミング/型システムの影響を解決した、解決可能、または単に面白くないと考えているかどうかはわかりません。
これらの同じ点の多くに当てはまる良いブログ投稿は、「可変長配列の合法的な使用」(Chris Wellons、2019-10-27)です。