Share via


/Zc:nrvo (控制選擇性 NRVO)

編譯器 /Zc:nrvo 選項會控制標準 C++ 選擇性的具名傳回值優化 (NRVO) 複製或移動 elision 行為。

語法

/Zc:nrvo[-]

備註

在 Visual Studio 2022 17.4 版和更新版本中,您可以使用編譯器選項明確啟用選擇性複製或移動 elision 行為 /Zc:nrvo 。 此選項預設為關閉,但會在您使用 /O2 選項、 /permissive- 選項或 /std:c++20 更新版本進行編譯時自動設定。 在 底下 /Zc:nrvo ,盡可能執行複製和移動 elision。 您也可以使用 /Zc:nrvo- 選項明確停用選擇性複製或移動 elision。 這些編譯器選項只會控制選擇性複製或移動 elision。 強制複製或移動 elision (C++ 標準所指定) 無法停用。

強制複製和移動 elision

當傳回的值初始化為 return 語句的一部分時,C++ 標準需要複製或移動 elision。 例如,當函式傳回使用 return ExampleType(); 傳回 ExampleType 的 時,這是必要的。 MSVC 編譯器一律會在需要時執行 return 語句的複製和移動 elision,即使在 下 /Zc:nrvo- 也是如此。

選擇性複製和移動 elision

return當語句包含非基本類型的運算式時,其執行會將運算式結果複製到呼叫函式的傳回位置。 編譯器會叫用傳回型別的複製或移動建構函式。 然後,當函式結束時,會呼叫函式區域變數的解構函式,其中包含運算式中任何名為 的變數。

C++ 標準允許編譯器選擇性地在呼叫函式的傳回位置中建構傳回的物件(但不需要)。 此建構會略過複製或 移動建構函式,做為 語句的 return 一部分執行。 與其他大多數優化不同,此轉換可以對程式的輸出產生可觀察的影響。 也就是說,複製或移動建構函式和相關聯的解構函式會呼叫較少的時間。 標準仍然需要具名傳回的變數具有已定義的複製或移動建構函式,即使編譯器在所有情況下都會將建構函式滑倒。

在 Visual Studio 2022 17.4 版之前的版本中,當優化停用時(例如在標示 #pragma optimize("", off) 的函式中 /Od )時,編譯器只會執行強制複製和移動 elision。 在 下 /O2 ,較舊的編譯器會在符合上述所有條件時,在優化函式中傳回具名變數時執行選擇性複製或移動 elision:它沒有迴圈或例外狀況處理,也不會傳回具有重迭存留期的多個符號、類型的複製或移動建構函式沒有預設引數。

Visual Studio 2022 17.4 版會增加編譯器在 下 /Zc:nrvo 執行選擇性複製或移動 elision 的位置數目,無論是明確啟用,還是使用 /O2/permissive-/std:c++20 更新版本選項自動啟用。 在 下 /Zc:nrvo ,編譯器會在傳回任何函式的具名變數時執行選擇性複製或移動 elision:它沒有迴圈或例外狀況處理(如先前所示):它會從迴圈傳回變數;它具有例外狀況處理;傳回型別的複製或移動建構函式具有預設引數。 套用 時 /Zc:nrvo- ,或函式傳回多個具有重迭存留期的符號,或針對具名變數擲回時,永遠不會執行選擇性複製或移動傳遞。

如需下 /Zc:nrvo 強制和選擇性複製 elision 的詳細資訊和範例,請參閱 C++ 小組部落格中的改善複製和移動 Elision

在 Visual Studio 中設定這個編譯器選項

  1. 開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性

  2. 選取 [組態屬性]>[C/C++]>[命令列] 屬性頁。

  3. [其他選項 ] 中,新增 /Zc:nrvo/Zc:nrvo- 。 選擇 [確定 ] 或 [ 套用 ] 以儲存您的變更。

另請參閱

/Zc (一致性)
/O2
/permissive-
/std (指定語言標準版本)