2009-06-04 69 views
15

一般來說,我傾向於使用try/catch代碼,該代碼具有多個失敗點,其中失敗點具有共同的處理程序。C++中try/catch塊的用法

根據我的經驗,這通常是在執行某些操作之後執行某些操作或輸出之前限定輸入或上下文的代碼。

我收到了來自文獻和同事的建議,儘量減少這些塊中的代碼,並且我接受這個建議。

我想了解更多的關於上述建議的基礎:

  • 什麼開銷的本質是什麼?
  • 是否有最近的開發指南解決try/catch塊的推薦使用(或避免)?
  • 更快的處理器和更現代的編譯器能夠緩解try/catch問題的多少?

在此先感謝您的幫助,

AJ

+0

我不確定我是否理解這個問題。你擔心try/catch塊的性能嗎?或者詢問使用try/catch來處理輸入驗證或什麼? – jalf 2009-06-04 15:54:50

+0

Dupe of http://stackoverflow.com/questions/43253/measuring-exception-handling-overhead-in-c其他許多人 – 2009-06-04 16:18:37

回答

0

以我的經驗用try/catch塊,最大的問題是,我們常常試圖捕獲異常也一般。例如,如果我用捕獲(...)的try/catch塊封裝我的主函數,我基本上不想讓我的程序崩潰拋出異常的b/c。

這種方法的問題,因爲我看到它是兩倍。 1)當我正在測試和調試時,我沒有看到任何錯誤,我沒有機會修復它們。 2)這是一種懶惰的方式。與其考慮可能出現的問題並找出邊緣情況是什麼,我只是想盡量避免失敗。嘗試不失敗與嘗試成功有很大的不同。

+1

你總是可以趕上並重新拋出。注意如果一個異常轉義了main(),它將在堆棧解開時定義實現(所以析構函數可能不會被調用)。因此,我總是抓住(...)並登錄main並重新拋出,以便獲取windows錯誤消息。 – 2009-06-04 18:56:01

5

第二個問題:一般指導原則是here, 香草薩特也給了很好的建議here

6

我發現了a technical report on C++ performance(pdf警告),其中包含有關例外的部分。你可能會覺得它很有趣。我有一些同事相信在try/catch塊中的每條指令都有開銷,但這份技術報告似乎並不支持這個想法。

0

在大多數語言中,通過常規方法進入和退出try/catch塊是免費的,只有當異常處理程序查找異常處理位置時纔會引發異常。

2

取決於編譯器。你爲什麼不用一個try-catch塊和一個沒有它的類似函數編寫一個簡單的函數,並比較生成的機器碼?

17

在C++中,成本取決於實現。一般來說,有兩種方法來實現例外:

第一種是「表格」方法。編譯器建立一組表查找,在拋出異常的地方,去哪裏。拋出異常時,必須搜索每個表中的調用堆棧,直到找到能夠捕獲此異常的東西。由於這是所有基於運行時的,所以進入或退出try catch不會產生任何懲罰(好),但拋出異常涉及潛在的許多查找,產生更慢的拋出。我個人更喜歡try-catch-try-try-catch,因爲異常應該是非常罕見的情況。如果必須存儲表格,這也會使可執行文件變大。

秒是「代碼」的方法。每次代碼進入try catch塊時,從概念上講,塊的位置被壓入堆棧。這會在進入和退出try-catch塊時產生成本,但是,當引發異常時,運行時機制可以快速彈出堆棧以找到要去的地方。所以,拋出異常(更快?),但現在進入一個塊有成本。將一個try catch塊放在一個低級別的循環中會產生很大的開銷。

你將不得不檢查你的具體編譯器,看看他們使用哪一個。

0

在C++中,您不應該使用try/catch塊來執行清理。相反,您可能想要使用模板來執行資源採集。

的auto_ptr的是一個[衰]例如

同步鎖,在那裏你存儲一個互斥體的狀態變量,使用局部變量(模板或者在普通類)來執行.acquire()/。釋放()方法。

您做的越多,您就越不必擔心在特殊情況下手動釋放對象。 C++編譯器會爲你做。