gcc __THROW的意義

轉(zhuǎn)載自網(wǎng)絡(luò)11年的文章,原址已不詳。
0. 引子
Linux/FreeBSD內(nèi)核的源文件里常會(huì)出現(xiàn)這個(gè)東東。其實(shí)并不復(fù)雜,只是簡(jiǎn)單的宏定義,可以參考以下代碼:
像這個(gè)
static void icmp6_errcount __P((struct icmp6errstat *, int, int));
展開(kāi)后就是
static void icmp6_errcount (struct icmp6errstat *, int, int) throw();
或者
static void icmp6_errcount (struct icmp6errstat *, int, int);
__P
在c++調(diào)用的情況下,會(huì)在函數(shù)聲明后加入throw()
表明該函數(shù)不會(huì)扔出異常, 這樣避免編譯器生成對(duì)異常的處理代碼, 優(yōu)化生成結(jié)果.
那么問(wèn)題變成了throw()又是個(gè)什么東東呢?
throw()是C++中聲明異常的指示,詳見(jiàn)下文:
1. c++ try_catch throw
1.1 基礎(chǔ)介紹
語(yǔ)法小結(jié):throw拋出值,catch接受,當(dāng)然,throw必須在“try語(yǔ)句塊”中才有效。
1.2 深入throw
程序接受到
throw
語(yǔ)句后就會(huì)自動(dòng)調(diào)用析構(gòu)器,把該域(try后的括號(hào)內(nèi))對(duì)象clean up,然后再進(jìn)入catch語(yǔ)句(如果在循環(huán)體中就退出循環(huán))。
這種機(jī)制會(huì)引起一些致命的錯(cuò)誤,比如,當(dāng)“類”有指針成員變量時(shí)(又是指針?。?,在“類的構(gòu)建器”中的throw語(yǔ)句引起的退出,會(huì)導(dǎo)致這個(gè)指針?biāo)赶虻膶?duì)象沒(méi)有被析構(gòu)。
這里很基礎(chǔ),就不深入了,提示一下,把指針改為類就行了,比如模板類來(lái)代替指針,在模板類的內(nèi)部設(shè)置一個(gè)析構(gòu)函數(shù)。
語(yǔ)句
throw;
拋出一個(gè)無(wú)法被捕獲的異常,即使是catch(…)也不能捕捉到,這時(shí)進(jìn)入終止函數(shù),見(jiàn)下catch。
1.3 深入catch:
一般的catch出現(xiàn)的形式是:
一般都寫(xiě)成引用(except1&),原因很簡(jiǎn)單,效率。
問(wèn)題a:拋出異常,但是catch不到異常怎么辦?(注意沒(méi)有java類似的finally語(yǔ)句)
在catch沒(méi)有捕獲到匹配的異常的時(shí)候,會(huì)調(diào)用默認(rèn)的終止函數(shù)??梢哉{(diào)用set_terminate()
來(lái)設(shè)置終止函數(shù),參數(shù)是一個(gè)函數(shù)指針,類型是:void (*terminate)()
。
到這里,可以提個(gè)問(wèn)題:“沒(méi)有try-catch,直接在程序中"throw;",會(huì)怎么樣?”
其他一些技巧:
1.4 try一個(gè)函數(shù)體,形式如下
這個(gè)用法的效果就相當(dāng)于:
void fun()?
{
? try{函數(shù)定義}?
}
1.5 throw一個(gè)函數(shù)體,形式如下:
問(wèn)題b:假設(shè)fun()中拋出了一個(gè)不在“異常參數(shù)表”中的異常,會(huì)怎么樣?
答:調(diào)用set_terminate()中設(shè)定的終止函數(shù)。然而,這只是表面現(xiàn)象,實(shí)際上是調(diào)用默認(rèn)的unexpected()
函數(shù),然而這個(gè)默認(rèn)的unexpected()調(diào)用了set_terminate()中設(shè)定的終止函數(shù)。可以用set_unexpected()來(lái)設(shè)置unexpected, 就像set_terminate()一樣的用法,但是在設(shè)定了新的“unexpected()”之后,就不會(huì)再調(diào)用set_terminater中設(shè)定的終止函數(shù)了。
這個(gè)語(yǔ)法是很有用的,因?yàn)樵谟脛e人的代碼時(shí),不知道哪個(gè)地方會(huì)調(diào)用什么函數(shù)又會(huì)拋出什么異常,用一個(gè)異常參數(shù)表在申明時(shí)限制一下,很實(shí)用。