/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 中設定這個編譯器選項
開啟專案的 [屬性頁] 對話方塊。 如需詳細資料,請參閱在 Visual Studio 中設定 C ++ 編譯器和組建屬性。
選取 [組態屬性]>[C/C++]>[命令列] 屬性頁。
在 [其他選項 ] 中,新增
/Zc:nrvo
或/Zc:nrvo-
。 選擇 [確定 ] 或 [ 套用 ] 以儲存您的變更。
另請參閱
意見反映
https://aka.ms/ContentUserFeedback。
即將推出:我們會在 2024 年淘汰 GitHub 問題,並以全新的意見反應系統取代並作為內容意見反應的渠道。 如需更多資訊,請參閱:提交及檢視以下的意見反映: