結構化例外狀況處理 (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 (例外狀況處理模型)。