ローカル変数を返すとコピーが返され、元の変数が破棄されますか (NRVO)?
はじめに:
この質問は、 C でローカル変数を返す動作を調べます。具体的には、返されたオブジェクトがコピーであるか元のオブジェクトであるか、またそれがローカル変数の破棄にどのような影響を与えるかを調べます。
戻り値の最適化 (NRVO):
With NRVO (戻り値の最適化という名前) を有効にすると、コンパイラーは return ステートメントを最適化し、不必要なコピーの構築やローカル変数の破壊を回避します。これは、戻りオブジェクトをターゲット ストレージに直接構築し、中間のコピーや移動のオーバーヘッドを排除することで実現されます。 NRVO は、ローカル変数に自動保存期間があり、戻り値の型と同じ型であるなど、特定の条件が満たされた場合に適用されます。
NRVO が有効な例:
次のコード:
class Test { public: Test(int p) { std::coutNRVO を有効にすると、出力は次のようになります:
Constructor called Destructor calledと呼ばれます。この場合、NRVO は return ステートメントを最適化し、オブジェクト o をローカル変数 t のストレージに直接構築します。コンストラクターは 1 回呼び出され、オブジェクト o に対して呼び出されるデストラクターは 1 つだけです。
NRVO が無効になっている例:
ただし、NRVO は -fno-elide- を使用して無効にできます。コンストラクターのコンパイラ フラグ。 NRVO を使用しない場合、コンパイラーはコピーの構築と破棄のステップを明示的に実行します。Constructor called Constructor called Destructor called Destructor calledこの場合、コンストラクターは 2 回呼び出されます (ローカル変数 t と戻りオブジェクト o に対して)。さらに、ローカル変数 t と戻りオブジェクト o は両方とも別々に破棄されます。
結論:
ローカル変数を返す動作は、NRVO が有効か無効かによって異なります。 NRVO を有効にすると、ローカル変数は最適化されなくなり、コンストラクターとデストラクターは戻りオブジェクトに対して 1 回だけ呼び出されます。 NRVO を使用しない場合、コピーの構築と破棄の手順が明示的に実行され、コンストラクターとデストラクターが複数回呼び出される可能性があります。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3