これは常に期待どおりに実行されますか?
char *x;
if (...) {
int len = dynamic_function();
char x2[len];
sprintf(x2, "hello %s", ...);
x = x2;
}
printf("%s\n", x);
// prints hello
コンパイラ (私の場合は GCC) は、C と C++ のそれぞれで可変サイズの配列をどのように実装しますか?
No.x2
はif
ステートメントのスコープに対してローカルであり、ポインターを使用してその外側にアクセスします。これにより、未定義の動作が発生します。
ところで、VLA は C11 でオプションになり、C++ の一部になることはありませんでした。だから避けたほうがいい。
The scope is explained here:
Jumping or breaking out of the scope of the array name deallocates the storage. Jumping into the scope is not allowed; you get an error message for it.
In your case the array is out of scope.
いいえ、次の 2 つの理由からです。
C++:コードは有効な C++ ではありません。C++ の配列には、コンパイル時の定数サイズが必要です。
C:いいえ、配列はそれが宣言されたブロックの終わりまでしか存在しないため、逆参照x
は未定義の動作です。
C11、6.2.4/2 から:
オブジェクトがその有効期間外に参照された場合、動作は未定義です。
そして 6.2.4/7 は、可変長配列がその宣言からそれを囲むスコープの終わりまで存続すると述べています。
可変長配列型を持つオブジェクトの場合、その有効期間は、オブジェクトの宣言から、プログラムの実行が宣言のスコープを離れるまで延長されます。