2011-05-13 62 views
3

作爲一名C程序員,我對異常沒有太多經驗。我習慣於將errno作爲跨多個函數調用進行通信錯誤的方式。這就是說,我沒有看到例外的顯着特徵,所以...異常與errno

例外和使用errno之間的根本區別是什麼?

+0

非常簡單:它是完全有效的,可以忽略異常。它具有出色的定義行爲。 – 2011-05-13 01:33:48

回答

3

這裏有這麼多的差異,很難說從哪裏開始。

首先,在C中使用的errno是一個全局變量;這意味着每個調用errno的子程序在執行任何其他工作前必須檢查errno,如果它關心正確性的話。幸運的是,errno is threadsafe

C++異常會自動解除調用堆棧,直到找到準備處理故障的函數。這意味着在大多數情況下,用戶不必顯式檢查每個呼叫的錯誤;相反,他們可以在一個地方收集錯誤回報。與errno不同,C++異常可以包含整數以外的值。

2

1)異常可以是任何東西,不只是一個整數。所以傳遞的數據是不同的。

2)異常做非本地控制流程,所以你不必在每個級別檢查在實踐中與errno的方式,你也返回一個值,指示錯誤,每個調用者檢查錯誤和保釋如果已經發生,就提前退出。相反,錯誤返回會執行本地控制流程,因此您始終可以準確查看錯誤何時通過給定的代碼傳播。這種差異從根本上改變了編碼風格。所以溝通方式也不同。

2

對我來說,最重要的區別是errno很容易被忽略,而異常很難忽略 - 如果最終忽略它們,程序將終止......另外,異常是(好的,應該是)對象,所以你可以攜帶更多有用的信息。

另一個非常重要的區別是,在軟件可以真正做出明智決定如何處理問題時,可以輕鬆地處理異常,通常是調用堆棧的幾個層次。這對於錯誤代碼來說並不容易。

3

你可以隨便忽略errno。必須處理例外情況。

當然,我已經看到了我的份額:

try { 
    // something 
} 
catch(...) { 
    // nothing 
} 
// continue as if nothing happened 

和(Java)的

try { 
    // something 
} 
catch(Throwable t) { 
    // nothing 
} 
// continue as if nothing happened 

但至少你這有點兒跳了出來,當你通過別人的爛攤子春耕。

3

我覺得不得不指出,在例外情況下編寫正確的程序並不容易。你最好做一些關於這個問題的研究,或許從Guru of the Week開始。只需查找exception這個詞。

1

我發現在嵌入式系統上有用的一種模式是爲每個流設置一個錯誤標誌,但規定當標誌設置時嘗試的I/O操作將立即失敗。因此,代碼可以這樣做:

 
    pkt_type = tcp_getbyte(my_stream, timeout); 
    pkt_length = tcp_getbyte(my_stream, timeout); 
    pkt_length |= tcp_getbyte(my_stream, timeout) << 8; 
    if (pkt_length < MAX_PACKET_LENGTH) 
    { 
    for (i=0; i<pkt_length; i++) 
     buffer[i] = tcp_getbyte(my_stream, timeout); 
    } 
    if (!my_stream->error) 
    { 
    /* Do something with packet */ 
    } 

如果一個試圖得到一個字節超時,隨後試圖將無條件失敗,返回零。沒有必要檢查每個操作的失敗;如果出現問題,系統最終會像tcp_getbyte()拋出異常一樣運行,只是速度不夠快。