/Zc:nrvo (オプションの NRVO を制御する)

コンパイラ オプションは /Zc:nrvo 、標準 C++ の省略可能な名前付き戻り値の最適化 (NRVO) のコピーまたは移動のエリジオン動作を制御します。

構文

/Zc:nrvo[-]

解説

Visual Studio 2022 バージョン 17.4 以降では、コンパイラ オプションを使用して、省略可能なコピーまたは移動の省略可能な動作を明示的に /Zc:nrvo 有効にすることができます。 このオプションは既定ではオフになっていますが、オプション、オプション、またはそれ/std:c++20以降を/O2使用してコンパイルすると自動的に/permissive-設定されます。 下では /Zc:nrvo、コピーと移動のエリジオンは可能な限り実行されます。 オプションのコピーまたは移動のエリジオンは、オプションを使用して明示的に無効に /Zc:nrvo- することもできます。 これらのコンパイラ オプションは、省略可能なコピーまたは移動のエリシオンのみを制御します。 必須のコピーまたは移動のエリジオン (C++ 標準で指定) を無効にすることはできません。

必須のコピーと移動のエリシオン

C++ 標準では、戻り値が return ステートメントの一部として初期化されるときに、コピーまたは移動の省略が必要です。 たとえば、関数が戻り値を返ExampleTypereturn ExampleType();すときに必要です。 MSVC コンパイラは、ステートメントが必要な場合でも、ステートメントのコピーと移動の省略 return を常に実行します /Zc:nrvo-

省略可能なコピーと移動のエリシオン

ステートメントに return プリミティブ以外の型の式が含まれている場合、その実行によって式の結果が呼び出し元の関数の戻りスロットにコピーされます。 コンパイラは、返された型のコピーコンストラクターまたは移動コンストラクターを呼び出します。 次に、関数が終了すると、関数ローカル変数のデストラクターが呼び出されます。これには、式に名前が付けられた変数が含まれます。

C++ 標準では、コンパイラは必要に応じて、呼び出し元の関数のリターン スロットで返されたオブジェクトを直接構築できます (ただし、必要ありません)。 この構造では、ステートメントの一部returnとして実行されるコピーコンストラクターまたは移動コンストラクターがスキップ (または省略) されます。 他のほとんどの最適化とは異なり、この変換はプログラムの出力に観測可能な影響を与える可能性があります。 つまり、コピーまたは移動コンストラクターと関連付けられたデストラクターは、1 回少ない時間で呼び出されます。 標準では、コンパイラがすべてのケースでコンストラクターを省略した場合でも、返される名前付き変数に定義済みのコピーまたは移動コンストラクターが必要です。

Visual Studio 2022 バージョン 17.4 より前のバージョンでは、最適化が無効になっている場合 (下 /Od の関数やマークされた #pragma optimize("", off)関数など)、コンパイラは必須のコピーと移動の省略のみを実行します。 以前のコンパイラでは /O2、これらの条件がすべて満たされたときに、最適化された関数の名前付き変数の戻り値に対して省略可能なコピーまたは移動のエリシスを実行します。ループや例外処理がなく、有効期間が重複する複数のシンボルを返しません。型のコピーまたは移動コンストラクターには既定の引数はありません。

Visual Studio 2022 バージョン 17.4 では、コンパイラが省略可能なコピーや移動のエリジオン/Zc:nrvoを実行する場所の数が増えます。明示的に有効にされているか、または 、またはそれ以降のオプションを使用して/O2/permissive-/std:c++20自動的に有効になっているかは関係ありません。 コンパイラでは /Zc:nrvo、任意の関数の名前付き変数の戻り値に対して省略可能なコピーまたは移動の除外が実行されます。ループまたは例外処理がない (前と同様)、ループから変数が返されます。例外処理があります。返される型のコピーまたは移動コンストラクターには既定の引数があります。 省略可能なコピーまたは移動のエリジオンは、適用されたとき /Zc:nrvo- 、または関数が有効期間が重複する複数のシンボルを返すとき、または名前付き変数のスローに対して行われることはありません。

必須および省略可能なコピーのエリジオン/Zc:nrvoの詳細と例については、C++ チーム ブログの「コピーと移動のエリジオンの改善」を参照してください

このコンパイラ オプションを Visual Studio で使用するには

  1. プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。 詳細については、Visual Studio での C++ コンパイラとビルド プロパティの設定に関する記事を参照してください。

  2. [構成プロパティ]>[C/C++]>[コマンド ライン] プロパティ ページを選択します。

  3. [その他のオプション] で、追加/Zc:nrvoまたは /Zc:nrvo-. [OK] または [適用] を選択して、変更内容を保存します。

関連項目

/Zc (準拠)
/O2
/permissive-
/std (言語の標準バージョンの指定)