try-finally
陳述式是支援 C 和 C++ 語言中結構化例外狀況處理的 Microsoft 專有延伸模組。
語法
下列語法會描述 try-finally
陳述式:
// . . .
__try {
// guarded code
}
__finally {
// termination code
}
// . . .
文法
try-finally-statement
:
__try
compound-statement
__finally
compound-statement
try-finally
是 C 和 C++ 語言的 Microsoft 擴充功能,可讓目標應用程式在執行程式碼的區塊中斷時,仍可保證會執行清除程式碼。 清除包含如取消配置記憶體、關閉檔案和釋放檔案控制代碼等工作。 try-finally
陳述式對於有多個地方要檢查可能會導致常式過早傳回的錯誤時會特別有用。
如需相關資訊和程式碼範例,請參閱 try-except
陳述式。 如需結構化例外狀況處理的詳細資訊,請參閱結構化例外狀況處理。 如需使用 C++/CLI 在受管理應用程式中處理例外狀況的詳細資訊,請參閱在 /clr
下進行例外狀況處理。
注意
結構化例外狀況處理可搭配 Win32 處理 C 和 C++ 原始程式檔。 不過,它不是專為 C++ 所設計。 使用 C++ 例外狀況處理可確保您的程式碼更具可移植性。 此外,C++ 例外狀況處理更有彈性,因為它可以處理任何類型的例外狀況。 針對 C++ 程式,建議您使用 C++ 例外狀況處理機制 (try
、catch
和 throw
陳述式)。
__try
子句後面的複合陳述式是保護的區段。 __finally
子句後面的複合陳述式則是終止處理常式。 處理常式會指定一組退出受防護區段時執行的動作,無論退出受防護區段的原因是例外狀況 (異常終止) 或是正常執行 (正常終止)。
此時控制權會經由簡單的循序執行 (正常執行) 到達 __try
陳述式。 當控制項進入 __try
時,與其相關聯的處理常式會變成作用中。 如果控制流程到達 try 區塊的結尾,執行程序如下所示:
已叫用終止處理常式。
當終止處理常式完成時,便會從
__finally
陳述式之後繼續執行。 但是受防護區段會結束 (例如,藉由保護主體外部的goto
或是經由return
陳述式),終止處理常式會在控制流程移出受防護區段之前執行。__finally
陳述式不會封鎖搜尋適當例外狀況處理常式的動作。
如果在 __try
區塊中發生例外狀況,作業系統必須尋找例外狀況的處理常式,否則程式會失敗。 如果找到處理常式,則會執行任何及所有 __finally
區塊,並在處理常式中繼續執行。
例如,假設有一系列的函式呼叫連結了函式 A 與函式 D,如下圖所示。 每個函式都具有一個終止處理常式。 如果例外狀況在函式 D 中引發,並在函式 A 中處理,則會在系統回溯堆疊時,依此順序呼叫終止處理常式:D、C、B。
此圖表會從函式 A 開始,其會呼叫函式 B,其會呼叫函式 C,其會呼叫函式 D。函式 D 會引發例外狀況。 接著會依下列順序呼叫終止處理常式:D 的終止處理常式、然後是 C 的、B 的,然後 A 會處理例外狀況。
終止處理常式執行的順序
注意
try-finally 的行為與支援使用 finally
的其他語言 (例如 C#) 不同。 單一 __try
可能具有 __finally
和 __except
的其中一個 (但並非兩者)。 如果要同時使用兩個,外層的 try-except 陳述式必須以引號括住內部 try-finally 陳述式。 指定的規則在每個區塊執行時也不同。
為了與舊版相容,除非指定了編譯器選項 /Za
(停用語言延伸模組),否則 _try
、_finally
和 _leave
是 __try
、__finally
和 __leave
的同義字。
__leave 關鍵字
__leave
關鍵字只有在 try-finally
陳述式的受防護區段內才有效,而其作用是跳至受防護區段的結尾。 然後從終止處理常式中的第一個陳述式繼續執行。
goto
陳述式也可以跳出受防護區段,但不會降低效能,因為它不會導致堆疊回溯。 由於 __leave
陳述式不會導致堆疊回溯,因此會更有效率。
異常終止
使用 longjmp 執行階段函式結束 try-finally
陳述式會視為異常終止。 雖然跳入 __try
陳述式是不合法的,但跳出該陳述式是合法的。 起點 (__try
區塊的正常終止) 和目的地 (處理例外狀況的 __except
區塊) 之間的所有作用中 __finally
陳述式都必須執行。 這稱為區域回溯。
如果 __try
區塊因故提前終止 (包括跳出區塊),系統會執行相關的 __finally
區塊作為回溯堆疊處理序的一部分。 在這種情況下,如果從 __finally
區塊內呼叫,AbnormalTermination
函式會傳回 true
;否則會傳回 false
。
如果處理序在執行 try-finally
陳述式的中途遭到刪除,則不會呼叫終止處理常式。
結束 Microsoft 專有