次のコードでは
int& h() {
int o=100;
return o;
}
int main() {
int t=h(); //line 1
cout<<t; //line 2
return 0;
}
出力が 100 となる理由、つまり関数のローカル変数の値と、関数の戻り値の型が int& であるのに戻り値を int に返しているため、1 行目にエラーがない理由。
次のコードでは
int& h() {
int o=100;
return o;
}
int main() {
int t=h(); //line 1
cout<<t; //line 2
return 0;
}
出力が 100 となる理由、つまり関数のローカル変数の値と、関数の戻り値の型が int& であるのに戻り値を int に返しているため、1 行目にエラーがない理由。
ローカル変数への参照またはポインタを返すべきではありません。関数が戻るとすぐに破棄されます。スタックがまだ上書きされていない可能性があるため、場合によっては機能しているように見えることがあります。しかし、最終的には予想外に失敗します。
何かへの参照を同じ型の値に割り当てることは正当です。したがって、割り当てでコピーが作成されます。
値は 100 です。これは、それを含むメモリが解放されたばかりで、誰も何も書き込んでいないためです。別の例を次に示します。
int& h() {
int o=100;
return o;
}
int& h2()
{
int o = 10;
return o;
}
int main() {
int t=h() + h2(); //line 1
cout << t;
return 0;
}
これを Visual Studio で最適化せずにコンパイルすると、結果は 20 になり、次のようになります。
int &からint を設定してもエラーにはなりません。これは、「この参照を何らかのオブジェクトに取得し、そこにあるものをローカル変数にコピーする」ことを意味する有効な操作です。
参照ローカル変数を返す - シングル スレッド アプリケーションの場合 /example by Ivan/ は問題ありません。マルチスレッド アプリケーションの問題 - 異なるスレッドが h() などの関数を使用する場合。この場合、スレッドが使用中のメモリを割り当て解除する瞬間が発生する可能性があります。
コンパイラは、必ずしも悪い動作や未定義の動作から保護するとは限りません。
コンパイラに渡すオプションを確認してください。
codepad.org でコードをコンパイルすると、警告が生成されます: http://codepad.org/ParI4AOG
In function 'int& h()':
Line 6: warning: reference to local variable 'o' returned