青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統(tǒng)計(jì)

最新評(píng)論

SEH的強(qiáng)大功能之二(轉(zhuǎn))

上一篇文章講述了SEH的異常處理機(jī)制,也即try-except模型的使用規(guī)則。本篇文章繼續(xù)探討SEH另外一項(xiàng)很重要的機(jī)制,那就是“有效保證資源的清除”,其實(shí)這才是SEH設(shè)計(jì)上最為精華的一個(gè)東東,對(duì)于C程序而言,它貢獻(xiàn)簡(jiǎn)直是太大了。

  SEH的這項(xiàng)機(jī)制被稱為結(jié)束處理(Termination Handling),它是通過try-finally語句來實(shí)現(xiàn)的,下面開始討論吧!

try-finally的作用


  對(duì)于try-finally的作用,還是先看看MSDN中怎么說的吧!摘略如下:

The try-finally statement is a Microsoft extension to the C and C++ languages that enables 32-bit target applications to guarantee execution of cleanup code when execution of a block of code is interrupted. Cleanup consists of such tasks as deallocating memory, closing files, and releasing file handles. The try-finally statement is especially useful for routines that have several places where a check is made for an error that could cause premature return from the routine.

  上面的這段話的內(nèi)容翻譯如下:

  try-finally語句是Microsoft對(duì)C和C++語言的擴(kuò)展,它能使32位的目標(biāo)程序在異常出現(xiàn)時(shí),有效保證一些資源能夠被及時(shí)清除,這些資源的清除任務(wù)可以包括例如內(nèi)存的釋放,文件的關(guān)閉,文件句柄的釋放等等。try-finally語句特別適合這樣的情況下使用,例如一個(gè)例程(函數(shù))中,有幾個(gè)地方需要檢測(cè)一個(gè)錯(cuò)誤,并且在錯(cuò)誤出現(xiàn)時(shí),函數(shù)可能提前返回。

try-finally的語法規(guī)則

   上面描述try-finally機(jī)制的有關(guān)作用時(shí),也許一時(shí)我們還難以全面理解,不過沒關(guān)系,這里還是先看一下try-finally的語法規(guī)則吧!其實(shí)它很簡(jiǎn)單,示例代碼如下:

//seh-test.c
#include <windows.h>
#include <stdio.h>

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

puts("world");
}

上面的程序運(yùn)行結(jié)果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

  try-finally語句的語法與try-except很類似,稍有不同的是,__finally后面沒有一個(gè)表達(dá)式,這是因?yàn)閠ry- finally語句的作用不是用于異常處理,所以它不需要一個(gè)表達(dá)式來判斷當(dāng)前異常錯(cuò)誤的種類。另外,與try-except語句類似,try- finally也可以是多層嵌套的,并且一個(gè)函數(shù)內(nèi)可以有多個(gè)try-finally語句,不管它是嵌套的,或是平行的。當(dāng)然,try-finally多層嵌套也可以是跨函數(shù)的。這里不一一列出示例,大家可以自己測(cè)試一番。
另外,對(duì)于上面示例程序的運(yùn)行結(jié)果,是不是覺得有點(diǎn)意料之外呢?因?yàn)?__finally塊中的put(“__finally塊中”)語句也被執(zhí)行了。是的,沒錯(cuò)!這就是try-finally語句最具有魔幻能力的地方,即 “不管在何種情況下,在離開當(dāng)前的作用域時(shí),finally塊區(qū)域內(nèi)的代碼都將會(huì)被執(zhí)行到”。呵呵!這的確是很厲害吧!為了驗(yàn)證這條規(guī)則,下面來看一個(gè)更典型示例,代碼如下:

#include <stdio.h>

void main()
{
puts("hello");
__try
{
puts("__try塊中");

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

puts("world");
}

上面的程序運(yùn)行結(jié)果如下:
hello
__try塊中
__finally塊中
Press any key to continue

  上面的程序運(yùn)行結(jié)果是不是有點(diǎn)意思。在__try塊區(qū)域中,有一條return語句讓函數(shù)直接返回了,所以后面的put(“world”)語句沒有被執(zhí)行到,這是很容易被理解的。但是請(qǐng)注意,__finally塊區(qū)域中的代碼也將會(huì)被予以執(zhí)行過了,這是不是進(jìn)一步驗(yàn)證了上面了那條規(guī)則,呵呵!阿愚深有感觸的想:“__finally的特性真的很像對(duì)象的析構(gòu)函數(shù)”,朋友們覺得如何呢?

   另外,大家也許還特別關(guān)心的是,goto語句是不是有可能破壞上面這條規(guī)則呢?因?yàn)樵贑語言中,goto語句一般直接對(duì)應(yīng)一條jmp跳轉(zhuǎn)指令,所以如果真的如此的話,那么goto語句很容易破壞上面這條規(guī)則。還是看一個(gè)具體的例子吧!

#include <stdio.h>

void main()
{
puts("hello");
__try
{
puts("__try塊中");

// 跳轉(zhuǎn)指令
goto RETURN;
}
__finally
{
puts("__finally塊中");
}

RETURN:
puts("world");
}

上面的程序運(yùn)行結(jié)果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

  呵呵!即便上面的示例程序中,goto語句跳過了__finally塊,但是__finally塊區(qū)域中的代碼還是被予以執(zhí)行了。當(dāng)然,大家也許很關(guān)心這到底是為什么?為什么try-finally語句具有如此神奇的功能?這里不打算深入闡述,在后面闡述SEH實(shí)現(xiàn)的時(shí)候會(huì)詳細(xì)分析到。這里朋友們只牢記一點(diǎn),“不管是順序的線性執(zhí)行,還是return語句或goto語句無條件跳轉(zhuǎn)等情
況下,一旦執(zhí)行流在離開當(dāng)前的作用域時(shí),finally塊區(qū)域內(nèi)的代碼必將會(huì)被執(zhí)行”

try-finally塊中的異常


  上面只列舉了return語句和goto語句的情況下,但是如果程序中出現(xiàn)異常的話,那么finally塊區(qū)域內(nèi)的代碼還會(huì)被執(zhí)行嗎?上面所講到的那條規(guī)則仍然正確嗎?還是看看示例,代碼如下:

#include <stdio.h>

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

// 下面拋出一個(gè)異常
p = 0;
*p = 25;
}
__finally
{
// 這里會(huì)被執(zhí)行嗎
puts("__finally塊中");
}

puts("world");
}

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

上面的程序運(yùn)行結(jié)果如下:
hello
__try塊中
__finally塊中
__except塊中
Press any key to continue

  從上面示例程序的運(yùn)行結(jié)果來看,它是和“不管在何種情況下,在離開當(dāng)前的作用域時(shí),finally塊區(qū)域內(nèi)的代碼都將會(huì)被執(zhí)行到”這條規(guī)則相一致的。

__leave關(guān)鍵字的作用

  其實(shí),總結(jié)上面的__finally塊被執(zhí)行的流程時(shí),無外乎三種情況。第一種就是順序執(zhí)行到__finally塊區(qū)域內(nèi)的代碼,這種情況很簡(jiǎn)單,容易理解;第二種就是goto語句或return語句引發(fā)的程序控制流離開當(dāng)前__try塊作用域時(shí),系統(tǒng)自動(dòng)完成對(duì)__finally塊代碼的調(diào)用;第三種就是由于在__try塊中出現(xiàn)異常時(shí),導(dǎo)致程序控制流離開當(dāng)前__try塊作用域,這種情況下也是由系統(tǒng)自動(dòng)完成對(duì)__finally塊的調(diào)用。無論是第 2種,還是第3種情況,毫無疑問,它們都會(huì)引起很大的系統(tǒng)開銷,編譯器在編譯此類程序代碼時(shí),它會(huì)為這兩種情況準(zhǔn)備很多的額外代碼。一般第2種情況,被稱為“局部展開(LocalUnwinding)”;第3種情況,被稱為“全局展開(GlobalUnwinding)”。在后面闡述SEH實(shí)現(xiàn)的時(shí)候會(huì)詳細(xì)分析到這一點(diǎn)。
第3種情況,也即由于出現(xiàn)異常而導(dǎo)致的“全局展開”,對(duì)于程序員而言,這也許是無法避免的,因?yàn)槟阍诶卯惓L幚頇C(jī)制提高程序可靠健壯性的同時(shí),不可避免的會(huì)引起性能上其它的一些開銷。呵呵!這世界其實(shí)也算瞞公平的,有得必有失。

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

#include <stdio.h>

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

// 直接跳出當(dāng)前的__try作用域
__leave;
p = 0;
*p = 25;
}
__finally
{
// 這里會(huì)被執(zhí)行嗎?當(dāng)然
puts("__finally塊中");
}

puts("world");
}

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

上面的程序運(yùn)行結(jié)果如下:
hello
__try塊中
__finally塊中
world
Press any key to continue

  這就是__leave關(guān)鍵字的作用,也許大家在編程時(shí)很少使用它。但是請(qǐng)注意,如果你的程序中,尤其在那些業(yè)務(wù)特別復(fù)雜的函數(shù)模塊中,既采用了SEH機(jī)制來保證程序的可靠性,同時(shí)代碼中又擁有大量的goto語句和return語句的話,那么你的源代碼編譯出來的二進(jìn)制程序?qū)⑹鞘衷愀獾模粌H十分龐大,而且效率也受很大影響。此時(shí),建議不妨多用__leave關(guān)鍵字來提高程序的性能。

try-finally深入


  現(xiàn)在,相信我們已經(jīng)對(duì)try-finally機(jī)制有了非常全面的了解,為了更進(jìn)一步認(rèn)識(shí)try-finally機(jī)制的好處(當(dāng)然,主人公阿愚認(rèn)為,那些寫過Windows平臺(tái)下設(shè)備驅(qū)動(dòng)程序的朋友一定深刻認(rèn)識(shí)到try-finally機(jī)制的重要性),這里給出一個(gè)具體的例子。還記得,在《第21集 Windows系列操作系統(tǒng)平臺(tái)中所提供的異常處理機(jī)制》中,所講述到的采用setjmp和longjmp異常處理機(jī)制實(shí)現(xiàn)的那個(gè)簡(jiǎn)單例程嗎?現(xiàn)在如果有了try-finally機(jī)制,將能夠很容易地來避免內(nèi)存資源的泄漏,而且還極大地提高了程序模塊的可讀性,減少程序員由于不小心造成的程序bug等隱患。采用SEH重新實(shí)現(xiàn)的代碼如下:

#include <stdio.h>
#include <stdlib.h>

void test1()
{
char* p1, *p2, *p3, *p4;

__try
{
p1 = malloc(10);
p2 = malloc(10);
p3 = malloc(10);
p4 = malloc(10);

// do other job
// 期間可能拋出異常
}
__finally
{
// 這里保證所有資源被及時(shí)釋放
if(p1) free(p1);
if(p2) free(p2);
if(p3) free(p3);
if(p4) free(p4);
}
}

void test()
{
char* p;

__try
{
p = malloc(10);

// do other job
// 期間可能拋出異常

test1();

// do other job
}
__finally
{
// 這里保證資源被釋放
if(p) free(p);
}
}

void main( void )
{
__try
{
char* p;

__try
{
p = malloc(10);

// do other job

// 期間可能拋出異常
test();

// do other job
}
__finally
{
// 這里保證資源被釋放
if(p) free(p);
}
}
__except(1)
{
printf("捕獲到一個(gè)異常\n");
}
}

  呵呵!上面的代碼與采用setjmp和longjmp機(jī)制實(shí)現(xiàn)的代碼相比,是不是更簡(jiǎn)潔,更美觀。這就是try-finally語句的貢獻(xiàn)所在。

總結(jié)

   (1) “不管在何種情況下,在離開當(dāng)前的作用域時(shí),finally塊區(qū)域內(nèi)的代碼都將會(huì)被執(zhí)行到”,這是核心法則。

   (2) try-finally語句的作用相當(dāng)于面向?qū)ο笾械奈鰳?gòu)函數(shù)。

   (3) goto語句和return語句,在其它少數(shù)情況下,break語句以及continue語句等,它們都可能會(huì)導(dǎo)致程序的控制流非正常順序地離開 __try作用域,此時(shí)會(huì)發(fā)生SEH的“局部展開”。記住,“局部展開”會(huì)帶來較大的開銷,因此,程序員應(yīng)該盡可能采用__leave關(guān)鍵字來減少一些不必要的額外開銷。

  通過這幾篇文章中對(duì)SEH異常處理機(jī)制的深入闡述,相信大家已經(jīng)能夠非常熟悉使用SEH來進(jìn)行編程了。下一篇文章把try-except和try-finally機(jī)制結(jié)合起來,進(jìn)行一個(gè)全面而綜合的評(píng)述,繼續(xù)吧!

posted on 2008-01-25 19:29 大龍 閱讀(541) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产精品高清免费在线观看| 久久精品国产999大香线蕉| 欧美精品不卡| 免费成人黄色| 欧美日本韩国一区| 欧美激情女人20p| 欧美视频一区二区三区在线观看 | 久久久久国产精品一区二区| 香蕉国产精品偷在线观看不卡| 欧美一区二区免费视频| 老牛影视一区二区三区| 欧美人交a欧美精品| 国产精品视频你懂的| 一区精品久久| 中日韩视频在线观看| 欧美在线视频网站| 亚洲国产va精品久久久不卡综合| 久久午夜电影| av成人免费| 久久另类ts人妖一区二区| 久久在线视频在线| 国产精品毛片大码女人| 亚洲国产精品一区二区www在线| 一区二区三区免费在线观看| 久久久久国产精品一区三寸| 日韩午夜av| 美女成人午夜| 国内精品久久久| 一区二区三区毛片| 欧美高清视频一区二区三区在线观看| 亚洲视频一区在线| 牛牛影视久久网| 国产麻豆午夜三级精品| 99re热这里只有精品视频| 老司机午夜精品视频| 亚洲一区精彩视频| 欧美日本精品在线| 亚洲国产日韩在线一区模特| 久久精品电影| 亚洲免费在线观看| 欧美三级午夜理伦三级中文幕 | 亚洲欧美日韩综合aⅴ视频| 欧美成人午夜剧场免费观看| 午夜在线观看欧美| 国产精品日本精品| 在线视频免费在线观看一区二区| 亚洲免费精彩视频| 欧美不卡视频一区发布| 欧美一区二区三区在| 欧美三级精品| 亚洲一区二区三区影院| 日韩视频免费观看高清在线视频| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲尤物视频在线| 欧美日韩免费一区二区三区视频| 亚洲日本va午夜在线电影| 乱中年女人伦av一区二区| 翔田千里一区二区| 国产欧美日韩综合一区在线观看| 午夜精品在线| 亚洲欧美文学| 国内精品久久久久久久影视麻豆| 久久aⅴ乱码一区二区三区| 先锋影音久久| 亚洲大片精品永久免费| 欧美激情中文字幕在线| 欧美精品网站| 欧美大学生性色视频| 欧美中文字幕视频在线观看| 国产精品黄页免费高清在线观看| 欧美在线国产| 久久亚洲国产精品一区二区| 国产一区亚洲| 久久午夜视频| 美女网站在线免费欧美精品| 亚洲娇小video精品| 最新中文字幕一区二区三区| 欧美理论电影在线播放| 亚洲欧美日韩视频一区| 香蕉久久夜色| 亚洲狠狠婷婷| 亚洲无限av看| 亚洲成色777777女色窝| 亚洲精品欧美日韩专区| 欧美午夜视频在线观看| 亚洲一区二区欧美| 亚洲综合不卡| 久久久亚洲午夜电影| 亚洲神马久久| 国产亚洲综合精品| 亚洲福利视频免费观看| 国产精品v亚洲精品v日韩精品| 欧美在线一级va免费观看| 噜噜噜91成人网| 亚洲男同1069视频| 久久久久国产一区二区| 中文久久乱码一区二区| 久久精品视频在线| 亚洲一区二区三区四区五区黄| 久久天天躁狠狠躁夜夜爽蜜月| 免费成人在线视频网站| 欧美另类一区| 久久久久久九九九九| 欧美激情在线免费观看| 久久久久久久久岛国免费| 欧美精品三区| 老司机aⅴ在线精品导航| 欧美三级电影一区| 欧美va亚洲va日韩∨a综合色| 国产精品久久精品日日| 欧美激情国产精品| 国语自产精品视频在线看| 9i看片成人免费高清| 最新日韩在线视频| 久久久久久91香蕉国产| 欧美伊人久久大香线蕉综合69| 欧美日韩ab片| 欧美国产免费| 国语自产精品视频在线看8查询8 | 久久国产精品一区二区三区| 99国产精品| 美女视频黄免费的久久| 久久综合色天天久久综合图片| 国产欧美日韩一级| 亚洲女女做受ⅹxx高潮| 亚洲影院免费| 国产精品成人一区二区网站软件 | 韩国av一区二区三区四区| 亚洲在线免费| 亚洲欧美精品一区| 欧美色网一区二区| 日韩天天综合| 亚洲一区二区三区免费在线观看| 欧美日韩国产小视频| 91久久精品国产91久久性色| 91久久综合亚洲鲁鲁五月天| 你懂的视频欧美| 亚洲精品乱码久久久久久蜜桃91| 亚洲国产欧美一区二区三区同亚洲 | 久久久久久色| 黄色欧美日韩| 久久精品中文字幕一区二区三区| 久久精品欧美| 18成人免费观看视频| 美日韩精品视频免费看| 亚洲国产经典视频| av不卡在线| 国产精品婷婷午夜在线观看| 亚洲永久免费av| 久久国产精品毛片| 蜜臀91精品一区二区三区| 久久精品国产免费观看| 一本色道久久综合亚洲二区三区| 亚洲成色精品| 亚洲日本中文| 欧美日韩一区二区免费在线观看 | 性色av香蕉一区二区| 久久综合九九| 日韩午夜电影| 国产日韩精品久久久| 久久天天狠狠| 一本到高清视频免费精品| 欧美在线影院在线视频| 亚洲国产精品第一区二区| 欧美三级午夜理伦三级中文幕| 欧美一级黄色网| 亚洲欧洲三级| 午夜一级在线看亚洲| 欧美中文字幕在线| 欧美日韩三级在线| 欧美一级视频免费在线观看| 亚洲电影天堂av| 亚洲欧美激情精品一区二区| 激情久久五月天| 国产精品h在线观看| 久久精品国产精品亚洲精品| 亚洲精品一区二区在线| 久久综合给合| 亚洲免费一在线| 亚洲欧洲日韩综合二区| 国产欧美一二三区| 欧美日韩在线视频首页| 狂野欧美激情性xxxx| 午夜精品福利在线观看| 亚洲人成在线播放网站岛国| 久久人体大胆视频| 亚洲欧美日韩国产| 91久久国产综合久久| 国产一区二区高清不卡| 国产精品国产三级国产aⅴ浪潮| 久热精品视频在线观看| 欧美亚洲一级| 亚洲永久免费观看| 在线视频精品一区| 亚洲精品久久| 最新中文字幕亚洲| 欧美国产一区视频在线观看| 久久久久国色av免费看影院| 午夜国产精品视频免费体验区| 中文高清一区|