C でローカル変数を返す場合、コピーの構築と破壊を避けるために名前付き戻り値の最適化 (NRVO) が利用されますか?

Susan Sarandon
リリース: 2024-11-10 02:21:02
オリジナル
397 人が閲覧しました

Does Returning a Local Variable in C   Utilize Named Return Value Optimization (NRVO) to Avoid Copy Construction and Destruction?

ローカル変数を返すとコピーが返され、元の変数が破棄されますか (NRVO)?

はじめに:
この質問は、 C でローカル変数を返す動作を調べています。具体的には、返されたオブジェクトがコピーであるか元のオブジェクトであるか、またそれがローカル変数の破棄にどのような影響を与えるかを調査します。

戻り値の最適化 (NRVO):
NRVO (戻り値の最適化という名前) を有効にすると、コンパイラーは return ステートメントを最適化し、不必要なコピーの構築やローカル変数の破壊を回避します。これは、戻りオブジェクトをターゲット ストレージに直接構築し、中間のコピーや移動のオーバーヘッドを排除することで実現されます。 NRVO は、ローカル変数に自動保存期間があり、戻り値の型と同じ型であるなど、特定の条件が満たされた場合に適用されます。

NRVO が有効な例:
次のコード:

class Test {
public:
    Test(int p) { std::cout << "Constructor called" << std::endl; }
    ~Test() { std::cout << "Destructor called" << std::endl; }
};

Test function() {
    Test t(5);  // local variable with automatic storage duration
    return t;    // return local variable
}

int main() {
    Test o = function();
    return 0;
}
ログイン後にコピー

NRVO を有効にすると、出力は次のようになります。 be:

Constructor called
Destructor called
ログイン後にコピー

この場合、NRVO は return ステートメントを最適化し、オブジェクト o をローカル変数 t のストレージに直接構築します。コンストラクターは 1 回呼び出され、オブジェクト o に対して呼び出されるデストラクターは 1 つだけです。

NRVO が無効になっている例:
ただし、-fno-elide- を使用して NRVO を無効にできます。コンストラクターのコンパイラ フラグ。 NRVO を使用しない場合、コンパイラーはコピーの構築と破棄のステップを明示的に実行します。

Constructor called
Constructor called
Destructor called
Destructor called
ログイン後にコピー

この場合、コンストラクターは 2 回呼び出されます (ローカル変数 t と戻りオブジェクト o に対して)。さらに、ローカル変数 t と戻りオブジェクト o は両方とも個別に破棄されます。

結論:
ローカル変数を返す動作は、NRVO が有効か無効かによって異なります。 NRVO を有効にすると、ローカル変数は最適化されなくなり、コンストラクターとデストラクターは戻りオブジェクトに対して 1 回だけ呼び出されます。 NRVO を使用しない場合、コピーの構築と破棄の手順が明示的に実行され、コンストラクターとデストラクターが複数回呼び出される可能性があります。

以上がC でローカル変数を返す場合、コピーの構築と破壊を避けるために名前付き戻り値の最適化 (NRVO) が利用されますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート