c異常處理

轉自:http://wangwiththewind.spaces.live.com/Blog/cns!B2B54F7FBFB797AA!151.entry

 

========================================================================

 

C庫頭文件<stdlib.h>提供了兩個終止程序的函數:abort()exit()。這兩個函數運行於異常生命期的45。它們都不會返回到其調用者中,並都導致程序結束。這樣,它們就是結束異常處理的最後一步。

    雖然兩個函數在概念上是相聯繫的,但它們的效果不同:

l         abort():程序異常結束。默認情況下,調用abort()導致運行期診斷和程序自毀。它可能會也可能不會刷新緩衝區、關閉被打開的文件及刪除臨時文件,這依賴於你的編譯器的具體實現。

l         exit():文明地結束程序。除了關閉文件和給運行環境返回一個狀態碼外,exit()還調用了你掛接的atexit()處理程序。

    一般調用abort()處理災難性的程序故障。因爲abort()的默認行爲是立即終止程序,你就必須負責在調用abort()前存儲重要數據。(當我們談論到<signal.h>時,你可以使得abort()自動調用clean up代碼。)

    相反,exit()執行了掛接在atexit()上的自定義clean up代碼。這些代碼被按照其掛接的反序執行,你可以把它們當作虛擬析構器。通過必要的clean up代碼,你可以安全地終止程序而沒有留下尾巴。

   無論abort()還是exit()都不會返回到它的調用者中,且都將導致程序結束。在這個意義上來說,它們都表現爲終止異常的最後一步。

    abort()exit()讓你無條件終止程序。你還可以有條件地終止程序。其實現體系是每個程序員所喜愛的診斷工具:斷言,定義於<assert.h>

     

       與刺激的abort()exit()相比,goto語句看起來是處理異常的更可行方案。不幸的是,goto是本地的:它只能跳到所在函數內部的標號上,而不能將控制權轉移到所在程序的任意地點(當然,除非你的所有代碼都在main體中)。

爲了解決這個限制,C函數庫提供了setjmp()longjmp()函數,它們分別承擔非局部標號和goto作用。頭文件<setjmp.h>申明瞭這些函數及同時所需的jmp_buf數據類型。

原理非常簡單:

l         setjmp(j)設置“jump”點,用正確的程序上下文填充jmp_buf對象j。這個上下文包括程序存放位置、棧和框架指針,其它重要的寄存器和內存數據。當初始化完jump的上下文,setjmp()返回0值。

l         以後調用longjmp(j,r)的效果就是一個非局部的goto或“長跳轉”到由j描述的上下文處(也就是到那原來設置jsetjmp()處)。當作爲長跳轉的目標而被調用時,setjmp()返回r1(如果r設爲0的話)。(記住,setjmp()不能在這種情況時返回0。)

 

    通過有兩類返回值,setjmp()讓你知道它正在被怎麼使用。當設置j時,setjmp()如你期望地執行;但當作爲長跳轉的目標時,setjmp()就從外面“喚醒”它的上下文。你可以用longjmp()來終止異常,用setjmp()標記相應的異常處理程序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章