2017-10-16 79 views
1

a few SO posts關於是否聲明main()使用函數嘗試塊語法valid syntax,並且普遍的共識似乎是它是完全有效的。這讓我想知道...是否有任何理由(性能,風格,線程同步,多線程)爲什麼一個不會使用此語法作爲main()作爲一般規則以更優雅地捕獲任何未處理的異常?爲什麼不使用function-try-block聲明main()?

顯然,理想情況下不會有未處理的異常,但是它們發生了,我認爲提供比操作系統特定的默認處理程序更豐富的信息會更好。例如,就我而言,我想爲用戶提供支持電子郵件地址,以便他們可以報告崩潰並讓我的程序向我的基於雲的崩潰日誌提交日誌。

+6

對於初學者,您可以在普通函數體中使用普通的try/catch,而不會混淆不知道此語法的人。 –

+0

與簡單的try/catch相比有什麼優勢 – 2017-10-16 19:58:29

+1

函數try塊主要用於構造函數,因此您可以捕獲在初始化程序列表中拋出的異常。 –

回答

0

如果碰巧有一個想要在catch塊中訪問的變量,則需要使用大括號來提供可見性。但即使這樣可以用嵌套try/catch來處理......

0

如果你捕捉到(否則)未捕獲的對象,你將無法通過檢查堆棧跟蹤來找出執行到達拋出的方式,因爲當異常處理程序執行時,堆棧已經被解除。

如果讓意外的異常是未捕獲,您可以檢查在終止處理程序中的堆棧跟蹤 - 這不是的標準保證,但因爲沒有標準的方式,這不是什麼大不了的事檢查堆棧跟蹤(在C++中)。您可以在程序中使用特定於平臺的API,也可以使用外部調試器進行檢查。

因此,例如在您的情況下,不捕獲異常的優點是您可以將堆棧跟蹤附加到您打算提交的日誌條目。

此外,有些情況下,catch塊無法處理異常。例如,當你拋出一個正在執行的析構函數時,拋出一個異常。因此,爲了處理這些「不可捕捉」的異常,無論如何您都需要終止處理程序,所以在未捕獲異常情況下重複功能幾乎沒有優勢。


至於你用來捕捉異常的語法,沒有區別。函數try塊不同的情況是構造函數,它允許捕獲子對象構造函數拋出的異常。

0

您可以輕鬆地轉換

int main() try { 
    // The real code of main 
} 
catch (...) 
{ 
} 

int realMain() 
{ 
    // The real code of main 
} 

int main() 
{ 
    try 
    { 
     return realMain(); 
    } 
    catch (...) 
    { 
    } 
} 

不失功能/行爲。

我會猜測你使用第一版還是第二版是一個團隊編碼實踐的問題。從編譯器和運行時間的角度來看,我沒有看到任何語義差異。

0

爲什麼人會不會使用這個語法的main()作爲一般規則趕上 任何未處理的異常的任何地方更優雅?與C

    1. 兼容性有時也沒有辦法更加妥善地處理未處理的異常。

    顯然,理想情況下不會有未處理的異常,但他們 發生,我覺得這是很好的,提供的東西比操作系統特定的默認處理更多的信息 。例如,在我的情況下,我想 喜歡爲用戶提供一個支持電子郵件地址,以便他們可以報告 的崩潰並讓我的程序提交一個日誌到我的基於雲的崩潰 日誌。

    如果發生意外異常,您不能確定是否可以正確處理它。如果您的示例中存在網絡錯誤異常,您會怎麼做。並試圖發送電子郵件導致另一個異常?當你不能確定你的數據沒有被破壞,並且你不能確定你的程序在這個錯誤後能夠正確運行時,可能會有其他錯誤。所以如果你不知道發生了什麼錯誤,最好讓你的程序崩潰。 您可以實現另一個「觀察者」服務,用於檢查進程是否正在運行,並且它是否已經崩潰,可以使用日誌和核心轉儲將電子郵件發送給用戶。

    2

    例如,在我的情況,我想給用戶

    好提供支持電子郵件地址,你打算怎麼做,在一個服務器沒有面向用戶界面?

    實際上,即使在面向用戶的組件中,如果您無法告訴catch塊中它們處於什麼狀態,您將如何執行該操作?

    而對於那些無法向用戶顯示任何有用信息的過程(或者首先沒有任何「用戶」概念),您會在catch塊中做什麼比默認terminate

    至於

    ...比特定於操作系統的默認處理更多的信息.​​..

    許多操作系統的默認行爲將保存過程執行狀態的完整快照,在未處理的異常被拋出的時候,將其發送到文件進行調試。作爲開發人員,我想不出許多默認行爲,這些行爲可能是更多信息。

    不可否認,我更喜歡作爲桌面應用程序的最終用戶更精美的東西,但這是C++程序的一個非常小的子集。

    相關問題