C++ 關鍵字 (try-finally)

來源:互聯網
上載者:User

try-finally語句是Microsoft對C和C++語言的擴充,它能使32位的目標程式在異常出現時,有效保證一些資源能夠被及時清除,這些資源的清除任務可以包括例如記憶體的釋放,檔案的關閉,檔案控制代碼的釋放等等。try-finally語句特別適合這樣的情況下使用,例如一個常式(函數)中,有幾個地方需要檢測一個錯誤,並且在錯誤出現時,函數可能提前返回。

#include <windows.h>
#include <stdio.h>

try-finally語句的文法與try-except很類似,稍有不同的是,__finally後面沒有一個運算式,這是因為try- finally語句的作用不是用於異常處理,所以它不需要一個運算式來判斷當前異常錯誤的種類。另外,與try-except語句類似,try- finally也可以是多層嵌套的,並且一個函數內可以有多個try-finally語句,不管它是嵌套的,或是平行的。當然,try-finally多層嵌套也可以是跨函數的。這裡不一一列出樣本,大家可以自己測試一番。
另外,對於上面樣本程式的運行結果,是不是覺得有點意料之外呢?因為 __finally塊中的put(“__finally塊中”)語句也被執行了。是的,沒錯!這就是try-finally語句最具有魔幻能力的地方,即 “不管在何種情況下,在離開當前的範圍時,finally塊地區內的代碼都將會被執行到”。呵呵!這的確是很厲害吧!為了驗證這條規則,下面來看一個更典型樣本,代碼如下:

#include <stdio.h>

void main()
{
puts(“hello”);
__try
{
puts(“__try塊中”);

// 注意,下面return語句直接讓函數返回了
return;
}
__finally
{
puts(“__finally塊中”);
}

puts(“world”);
}

上面的程式運行結果如下:
hello
__try塊中
__finally塊中
Press any key to continue

 

void main()
{
puts(“hello”);
__try
{
puts(“__try塊中”);
}
// 注意,這裡不是__except塊,而是__finally取代
__finally
{
puts(“__finally塊中”);
}

puts(“world”);
}

上面的程式運行結果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

總結__finally塊被執行的流程時,無外乎三種情況。第一種就是順序執行到__finally塊地區內的代碼,這種情況很簡單,容易理解;第二種就是goto語句或return語句引發的程式控制流程離開當前__try塊範圍時,系統自動完成對__finally塊代碼的調用;第三種就是由於在__try塊中出現異常時,導致程式控制流程離開當前__try塊範圍,這種情況下也是由系統自動完成對__finally塊的調用。無論是第 2種,還是第3種情況,毫無疑問,它們都會引起很大的系統開銷,編譯器在編譯此類程式碼時,它會為這兩種情況準備很多的額外代碼。一般第2種情況,被稱為“局部展開(LocalUnwinding)”;第3種情況,被稱為“全域展開(GlobalUnwinding)”。在後面闡述SEH實現的時候會詳細分析到這一點。
第3種情況,也即由於出現異常而導致的“全域展開”,對於程式員而言,這也許是無法避免的,因為你在利用異常處理機制提高程式可靠健壯性的同時,不可避免的會引起效能上其它的一些開銷。呵呵!這世界其實也算瞞公平的,有得必有失。

  但是,對於第2種情況,程式員完全可以有效地避免它,避免“局部展開”引起的不必要的額外開銷。實際這也是與結構化程式設計思想相一致的,也即一個程式模組應該只有一個入口和一個出口,程式模組內盡量避免使用goto語句等。但是,話雖如此,有時為了提高程式的可讀性,程式員在編寫代碼時,有時可能不得不採用一些與結構化程式設計思想相悖的做法,例如,在一個函數中,可能有多處的return語句。針對這種情況,SEH提供了一種非常有效折衷方案,那就是__leave關鍵字所起的作用,它既具有像goto語句和return語句那樣類似的作用(由於檢測到某個程式運行中的錯誤,需要馬上離開當前的 __try塊範圍),但是又避免了“局部展開” 的額外開銷。還是看個例子吧!代碼如下:

#include <stdio.h>

void test()
{
puts(“hello”);
__try
{
int* p;
puts(“__try塊中”);

// 直接跳出當前的__try範圍
__leave;
p = 0;
*p = 25;
}
__finally
{
// 這裡會被執行嗎?當然
puts(“__finally塊中”);
}

puts(“world”);
}

void main()
{
__try
{
test();
}
__except(1)
{
puts(“__except塊中”);
}
}

上面的程式運行結果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.