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

雖然 Windows 和 Visual C++ 支援結構化處理 (SEH) 的例外狀況,因此我們建議您使用 ISO 標準 C++ 例外狀況處理,因為它可讓程式碼更具有可攜性和彈性。 然而,現有的程式碼或特定類型的程式中,您仍然必須使用 SEH。

文法

try-except-statement :

__try compound-statement

__except ( expression ) compound-statement

備註

使用 SEH,如果執行意外終止,可以確保資源 (例如記憶體區塊和檔案)正確。 您也可以處理特定問題 (例如,記憶體不足),使用不需要 goto 陳述式或傳回碼精心設計的測試來簡潔的結構化程式碼。

在這篇文章中提到的try-except和 try-finally 陳述式是 Microsoft 擴充功能 C 語言。 在另外終止執行的事件之後,它們可以讓應用程式支援 SEH 對程式控制項。 雖然 SEH 與 C++ 原始程式檔一起使用,它不為 C++ 特別設計。 如果您 在C ++. 程式會使用 SEH, 在編譯中使用解構函式 /EH 選項(與特定修飾詞) ,局域物件會被呼叫,但是其他執行行為可能不是您所預期的值。(如需範例,請參閱在本文中 範例 )。在大部分情況下取代 SEH,我們建議您使用 ISO 標準的 C++ 例外狀況處理。, Visual C++ 也支援。 使用 C++ 例外狀況處理,您可以確保您的程式碼更可移植的,因此,您可以處理任何型別的例外狀況。

如果您有使用 SEH 的 C# 模組,您可以使用 C++ 例外狀況處理的 C++ 模組混合它們。 如需詳細資訊,請參閱 例外狀況處理差異

有兩個SEH機制:

這兩種處理常式不同,不過,與稱為"回溯堆疊"的流程的關係密切。當例外狀況發生時, Windows 會尋找目前作用中的新安裝的例外處理常式。 處理程序可以執行三個中的期中一項:

  • 不能辨認例外狀況和傳遞控制項給另一個處理常式。

  • 辨識例外狀況,但是擱置它。

  • 辨識例外狀況並加以處理。

當發生例外狀況,辨識例外狀況的例外處理常式可能不在執行的函式。 在某些情況下,可能會在一個函式更高堆疊。 目前正在執行的函式和其他函式在堆疊框架結束。 在這個過程中,堆疊「未連結」,即區域變數終止函式,除非它們是 static—從堆疊中清除。

因為回溯堆疊,作業系統會告訴您為每個函式覆寫的任何終止處理常式。 使用終止處理常式,您可以清除由於異常終止而保持開啟狀態的資源。 如果您已進入關鍵區段,您在終止處理常式可以結束。 如果程式關閉,您可以執行其他維護工作 (例如關閉並刪除暫存檔。

如需詳細資訊,請參閱:

範例

如果您在 C ++. 程式使用 SEH 並編譯它,使用 /EH 選項修飾詞 (例如、 /EHsc/EHa,如先前陳述式,會呼叫區域物件的解構函式。 不過,如果您也使用 C++ 例外狀況,在執行期間可能並非您所預期。 下列範例會示範這些行為差異。

#include <stdio.h>
#include <Windows.h>
#include <exception>
 
class TestClass
{
public:
    ~TestClass()
    {
        printf("Destroying TestClass!\r\n");
    }
};
 
__declspec(noinline) void TestCPPEX()
{
#ifdef CPPEX
    printf("Throwing C++ exception\r\n");
    throw std::exception("");
#else
    printf("Triggering SEH exception\r\n");
    volatile int *pInt = 0x00000000;
    *pInt = 20;
#endif
}
 
__declspec(noinline) void TestExceptions()
{
    TestClass d;
    TestCPPEX();
}
 
int main()
{
    __try
    {
        TestExceptions();
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
        printf("Executing SEH __except block\r\n");
    }
 
    return 0;
}

如果您使用 /EHsc 編譯這個程式碼,但本機測試控制 CPPEX 未定義,會沒有 TestClass 解構函式的執行,並輸出如下所示:

  

如果您使用 /EHsc 編譯程式碼,並定義 CPPEX 使用 /DCPPEX (使 C ++.丟出例外狀況), TestClass 解構函式執行,並輸出如下所示:

  

如果您使用 /EHa 編譯程式碼,不管是否擲回例外狀況, TestClass 解構函式執行。您可以使用 std::throw 或使用 SEH 觸發例外狀況 (不論是否已定義CPPEX )。 輸出看起來像這樣:

  

如需詳細資訊,請參閱/EH (例外狀況處理模型)

請參閱

參考

Visual C++ 中的例外狀況處理

C++ 關鍵字

<exception>

概念

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

其他資源

結構化例外狀況處理