/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 中設定這個編譯器選項
開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性。
選取 [組態屬性]>[C/C++]>[命令列] 屬性頁。
在 [其他選項] 中,新增
/Zc:nrvo
或/Zc:nrvo-
。 選擇 [確定] 或 [套用] 以儲存變更。