Share via


/Zc:throwingNew (假設擲回運算子 new)

指定 /Zc:throwingNew 選項時,編譯器會將 呼叫優化為 operator new ,以略過 Null 指標傳回的檢查。 此選項會告知編譯器假設 和 自訂配置器的所有連結實作 operator new 都符合 C++ 標準,並在配置失敗時擲回。 根據預設,在 Visual Studio 中,編譯器會悲觀地產生這些呼叫的 Null 檢查( /Zc:throwingNew- ),因為使用者可以連結至傳回 Null 指標的非 operator new 擲回實作或寫入傳回 Null 指標的自訂配置器常式。

語法

/Zc:throwingNew [ - ]

備註

由於 ISO C++98,標準已指定當記憶體配置失敗時,預設 運算子 new std::bad_alloc 擲回。 最高為 Visual Studio 6.0 的 Visual C++ 版本在配置失敗時傳回 Null 指標。 從 Visual Studio 2002 開始, operator new 符合標準,並在失敗時擲回。 為了支援使用舊版配置樣式的程式碼,Visual Studio 提供 nothrownew.obj 中可連結的 operator new 實作,在失敗時傳回 Null 指標。 根據預設,編譯器也會產生防禦性 Null 檢查,以防止這些舊式配置器在失敗時立即當機。 /Zc:throwingNew 選項會告知編譯器排除這些 Null 檢查,假設所有連結的記憶體配置器都符合標準。 這不適用於明確非擲回 operator new 的多載,這些多載是使用 型 std::nothrow_t 別的其他參數來宣告,而且具有明確的 noexcept 規格。

就概念上講,若要在免費存放區上建立物件,編譯器會產生程式碼來配置其記憶體,然後叫用其建構函式來初始化記憶體。 因為 MSVC 編譯器通常無法判斷此程式碼是否會連結至不符合規範的非擲回配置器,因此它預設也會在呼叫建構函式之前產生 Null 檢查。 如果非擲回的配置失敗,這可防止建構函式呼叫中的 Null 指標取值。 在大部分情況下,這些檢查都是不必要的,因為預設 operator new 配置器會擲回,而不是傳回 Null 指標。 檢查也有不幸的副作用。 它們會膨脹程式碼大小、淹沒分支預測值,並禁止其他有用的編譯器優化,例如將虛擬化或 const 傳播移出初始化的物件。 檢查只存在於支援連結到 nothrownew.obj 或具有自訂不符合規範 operator new 實作的程式碼。 如果您未使用不符合 operator new 規範,建議您使用 /Zc:throwingNew 將程式碼優化。

/Zc:throwingNew 選項預設為關閉,而且不會受到 /permissive- 選項的影響。

如果您使用連結時間程式碼產生 (LTCG) 進行編譯,則不需要指定 /Zc:throwingNew 。 使用 LTCG 編譯器代碼時,編譯器可以偵測是否使用預設且符合規範的 operator new 實作。 如果是,編譯器會自動排除 Null 檢查。 連結器會尋找 /ThrowingNew 旗標,以判斷 的 operator new 實作是否符合規範。 您可以將這個旗標指定給連結器,方法是在自訂運算子新實作的來源中包含這個指示詞:

#pragma comment(linker, "/ThrowingNew")

如需 Visual C++ 中一致性問題的詳細資訊,請參閱 Nonstandard Behavior

在 Visual Studio 開發環境中設定這個編譯器選項

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

  2. 從 [ 組態 ] 下拉式功能表中,選擇 [ 所有組態 ]。

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

  4. 修改 [其他選項] 屬性以包含 /Zc:throwingNew /Zc:throwingNew- ,然後選擇 [ 確定 ]。

另請參閱

MSVC 編譯器選項
MSVC 編譯器命令列語法
/Zc (一致性)
noexcept (C++)
例外狀況規格 (throw) (C++)
terminate (exception)