共用方式為


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

編譯程式 /Zc:nrvo 選項會控制 Standard 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++ Standard 所指定)。

強制複製和移動 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 (指定語言標準版本)