請試著-除非陳述式
Microsoft 專有的
下列語法將告訴您試試看-除非陳述式:
__try
{
// guarded code
}
__except ( expression )
{
// exception handler code
}
備註
試-除了陳述式是 Microsoft 延伸到 c 和 C++ 語言可讓目標應用程式取得控制正常終止程式執行的事件發生時。這類事件稱為 「 例外狀況,而處理的例外狀況的機制就稱為結構化的例外處理。
如需相關資訊,請參閱 try-finally 陳述式。
例外狀況可以是硬體式 csp,或以軟體為基礎。即使在應用程式完全無法復原的硬體或軟體的例外狀況,結構化的例外處理讓顯示錯誤資訊,及設陷的應用程式,以協助診斷問題的內部狀態。這特別適用於間歇性無法輕易地重現的問題。
注意事項 |
---|
處理在 win32 中的運作方式,如 c 與 C++ 的來源檔的結構化例外狀況。不過,它是不被專門針對 C++。您可以確保您的程式碼使用 C++ 例外處理會更好移植。此外,C++ 例外處理會更有彈性,因為它可以處理任何型別的例外狀況。C + + 程式,建議您使用的 C++ 例外處理機制 (嘗試、 攔截,並擲回陳述式)。 |
複合陳述式之後, __try子句是主體或保護的區段。複合陳述式之後, __except子句是例外處理常式。這個處理常式指定一組保護區段主體的執行期間引發例外狀況時所要採取的動作。執行如下所示:
執行保護的區段。
如果執行保護的區段時,就會不發生任何例外狀況,在之後的陳述式會繼續執行__except子句。
如果保護的區段在執行期間發生例外狀況,或是在任何的常式會呼叫保護的區段, __except運算式 (稱為篩選運算式) 會評估和值會決定如何處理例外狀況。 有三個值:
EXCEPTION_CONTINUE_EXECUTION (– 1) 例外狀況就會關閉。發生例外狀況的點繼續執行。
EXCEPTION_CONTINUE_SEARCH (0) 無法辨識的例外狀況。抑制優先搜尋的處理常式,在堆疊中向上繼續試-除了陳述式,然後對下一個最高優先順序的處理常式。
EXCEPTION_EXECUTE_HANDLER (1) 例外狀況會辨識出來。將控制傳輸至例外狀況處理常式中,藉由執行__except複合陳述式,然後繼續執行之後, __except區塊。
因為 __除了為 c 運算式評估運算式,它是限制為單一值、 條件式運算式運算子或逗號運算子。如果需要更多的處理,運算式便可呼叫的常式會傳回其中一個三個以上所列的值。
每個應用程式可擁有自己的例外狀況處理常式。
它不能跳到應在__try陳述式,但若要跳足夠的有效。如果結束處理程序的執行,不會呼叫例外狀況處理常式試-除了陳述式。
如需詳細資訊,請參閱知識庫文件 Q315937: HOW TO: 設陷堆疊溢位在 Visual C++ 應用程式。
__Leave 關鍵字
__leave關鍵字是只能在保護的區段的try-except陳述式,而其效果會跳到保護區段結尾。在例外狀況處理常式後面的第一個陳述式會繼續執行。
A goto陳述式也可以跳完保護的區段,而且它不會降低效能,那般try-finally陳述式因為堆疊回溯不會發生。不過,我們建議您使用__leave關鍵字,而非goto陳述式因為您比較不容易犯了程式設計如果保護的區段大或很複雜。
結構化的例外處理內建函式
結構化的例外處理提供兩個內建的函式可以使用與試-除了 陳述式: GetExceptionCode 和 GetExceptionInformation。
GetExceptionCode 傳回例外狀況的程式碼 (32 位元整數)。
內建的函式 GetExceptionInformation 傳回的指標,此結構包含例外狀況的詳細資訊。透過這個指標,您可以存取的硬體例外狀況時存在的電腦狀態。結構如下所示:
struct _EXCEPTION_POINTERS {
EXCEPTION_RECORD *ExceptionRecord,
CONTEXT *ContextRecord }
指標型別 _EXCEPTION_RECORD 及 _ 等內容包含檔案 EXCPT 中所定義。H.
您可以使用 GetExceptionCode 在例外狀況處理常式中。不過,您可以使用 GetExceptionInformation 只在例外狀況篩選條件運算式。它指到的資訊通常是在堆疊上時,則不會再使用控制將轉移到的例外狀況處理常式。
內建的函式 AbnormalTermination 就出現在終止處理常式中。它會傳回 0,如果主體try-finally陳述式會依序終止。在其他情況下,它會傳回 1。
EXCPT。H 會定義一些其他的名稱,這些內建值:
GetExceptionCode 相當於 _exception_code
GetExceptionInformation 相當於 _exception_info
AbnormalTermination 相當於 _abnormal_termination
範例
// exceptions_try_except_Statement.cpp
// Example of try-except and try-finally statements
#include <stdio.h>
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
#include <excpt.h>
int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
puts("in filter.");
if (code == EXCEPTION_ACCESS_VIOLATION) {
puts("caught AV as expected.");
return EXCEPTION_EXECUTE_HANDLER;
}
else {
puts("didn't catch AV, unexpected.");
return EXCEPTION_CONTINUE_SEARCH;
};
}
int main()
{
int* p = 0x00000000; // pointer to NULL
puts("hello");
__try{
puts("in try");
__try{
puts("in try");
*p = 13; // causes an access violation exception;
}__finally{
puts("in finally. termination: ");
puts(AbnormalTermination() ? " \tabnormal" : "\tnormal");
}
}__except(filter(GetExceptionCode(), GetExceptionInformation())){
puts("in except");
}
puts("world");
}
Output
hello
in try
in try
in filter.
caught AV as expected.
in finally. termination:
abnormal
in except
world
結束 Microsoft 特定