共用方式為


/EH (例外狀況處理模型)

指定編譯器所使用的例外狀況處理類型,並終結會因例外狀況而超出範圍的 C++ 物件。 如果沒有指定 /EH,編譯器就會同時攔截非同步結構化例外狀況和 C++ 例外狀況,但不會終結因非同步例外狀況而超出範圍的 C++ 物件。

/EH{s|a}[c][-]

引數

  • a
    同時攔截非同步 (結構化) 例外狀況和同步 (C++) 例外狀況的例外狀況處理模型。

  • s
    只會攔截 C++ 例外狀況,並告知編譯器假設宣告為 extern "C" 的函式可能會擲回例外狀況的例外狀況處理模型。

  • c
    如果搭配 s (/EHsc) 使用,便只會攔截 C++ 例外狀況,並告知編譯器假設宣告為 extern "C" 的函式永遠不會擲回 C++ 例外狀況。

    /EHca 相當於 /EHa

備註

/EHa 編譯器選項可搭配原生 C++ catch(...) 子句,用來支援非同步結構化例外狀況處理 (SEH)。 若要實作 SEH 而不指定 /EHa,您可以使用 __try、__except 和 __finally 語法。 雖然 Windows 和 Visual C++ 支援 SEH,但是我們強烈建議您使用 ISO 標準 C++ 例外狀況處理 (/EHs/EHsc),因為它可提升程式碼的可攜性和彈性。 儘管如此,在現有程式碼中或針對特定類型的程式,像是編譯為支援通用語言執行平台 (/clr (Common Language Runtime 編譯)) 的程式碼,您仍然必須使用 SEH。 如需詳細資訊,請參閱結構化例外狀況處理 (C/C++)

使用 catch(...) 指定 /EHa 並嘗試處理所有例外狀況可能並不安全。 在大部分情況下,非同步例外狀況無法復原,因此應視為嚴重。 攔截這些例外狀況並繼續執行可能造成處理序損毀,因而導致難以找出並修正的 Bug。

如果您使用 /EHs/EHsc,那麼您的 catch(...) 子句就不會攔截非同步的結構化例外狀況。 存取違規和 Managed Exception 例外狀況並不會遭到攔截,而產生非同步例外狀況時不會終結範圍內的物件,即使已處理非同步例外狀況也一樣。

如果您使用 /EHa,影像可能較大且可能無法執行,因為編譯器不會積極地最佳化 try 區塊,而且即使未發現任何可能擲回 C++ 例外狀況的程式碼,編譯器仍會在例外況狀中留下自動呼叫所有本機物件之解構函式的篩選。 這樣就能安全地回溯非同步例外狀況以及 C++ 例外狀況的堆疊。 當您使用 /EHs 時,編譯器會假設例外狀況只能在 throw 陳述式或在函式呼叫中發生。 這樣編譯器就能夠消除追蹤許多無法回溯物件之存留期的程式碼,進而大幅縮小程式碼。

建議您不要在相同可執行模組中,將使用 /EHa 編譯的物件與使用 /EHs 編譯的物件連結在一起。 如果您必須在模組中的任何位置使用 /EHa 處理非同步例外狀況,請使用 /EHa 編譯模組中的所有程式碼。 您可以在與使用 /EHs 編譯的程式碼所在位置相同的模組中使用結構化例外狀況處理語法,但是不能在相同函式中混用 SEH 語法與 try、throw 和 catch。

如果您要攔截並非 throw 所引發的例外狀況,請使用 /EHa。 這個範例將會產生並攔截結構化例外狀況:

// compiler_options_EHA.cpp
// compile with: /EHa
#include <iostream>
#include <excpt.h>
using namespace std;

void fail() {   // generates SE and attempts to catch it using catch(...)
   try {
      int i = 0, j = 1;
      j /= i;   // This will throw a SE (divide by zero).
      printf("%d", j); 
   }
   catch(...) {   // catch block will only be executed under /EHa
      cout<<"Caught an exception in catch(...)."<<endl;
   }
}

int main() {
   __try {
      fail(); 
   }

   // __except will only catch an exception here
   __except(EXCEPTION_EXECUTE_HANDLER) {   
   // if the exception was not caught by the catch(...) inside fail()
      cout << "An exception was caught in __except." << endl;
   }
}

/EHc 選項要求必須指定 /EHs/EHa。 使用 /clr 就會隱含 /EHa (也就是說,/clr /EHa 是多餘的)。 如果在 /clr 之後使用 /EHs[c],編譯器就會產生錯誤。 最佳化作業不會影響這種行為。 攔截到例外狀況時,編譯器會叫用類別解構函式,或是與例外狀況位於相同範圍中的一個或多個物件的解構函式。 如果未攔截到例外狀況,則不會執行這些解構函式。

如需 /clr 下的例外狀況處理限制的詳細資訊,請參閱 _set_se_translator

使用 - 符號就可以清除選項。 例如,/EHsc- 會解譯為 /EHs /EHc-,相當於 /EHs

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

  1. 開啟專案的 [屬性頁] 對話方塊。 如需詳細資訊,請參閱 如何:開啟專案屬性頁

  2. 在左窗格中,展開 [組態屬性]、[C/C++]、[程式碼產生]。

  3. 修改 [啟用 C++ 例外狀況] 屬性。

    或者,將 [啟用 C++ 例外狀況] 設定為 [],然後在 [命令列] 屬性頁的 [其他選項] 方塊中,加入編譯器選項。

若要以程式方式設定這個編譯器選項

請參閱

參考

編譯器選項

設定編譯器選項

例外狀況規格

結構化例外狀況處理 (C/C++)

概念

錯誤和例外狀況處理 (現代 C++)