c++ - 異常處理 - stdexcept




Google C++風格指南的無例外規則; STL? (5)

谷歌的C ++風格指南說“我們不使用例外”。 關於異常的使用,樣式沒有提到STL。 由於STL分配器可能會失敗,它們如何處理容器拋出的異常?

  1. 如果他們使用STL,呼叫者如何獲知分配失敗? 像push_back()或map operator[]這樣的STL方法不會返回任何狀態代碼。
  2. 如果他們不使用STL,他們使用什麼容器實現?

Stl本身直接只在內存分配失敗的情況下拋出。 但通常情況下,真實世界的應用程序可能由於各種原因而失敗,內存分配失敗只是其中之一。 在32位系統上,內存分配失敗不應該被忽略,因為它可能發生。 所以上面關於內存分配失敗不會發生的整個討論都是毫無意義的。 即使假設這樣,也必須使用兩步初始化來編寫一個代碼。 而C ++異常處理早在64位架構之前就已存在。 我不確定我應該在多大程度上尊重谷歌所展示的負面職業精神,只回答問題。 我記得IBM在1997年左右發表的一篇論文,指出IBM的一些人理解和欣賞C ++異常處理的含義。 好的專業精神並不是成功的必要條件。 因此,如果使用STL,放棄異常處理不僅是一個問題。 如果使用C ++就是一個問題。 這意味著放棄

  • 構造函數失敗
  • 能夠使用成員對象和基類對像作為任何以下基類/成員類構造函數的參數(無需任何測試)。 毫無疑問,在C ++異常處理存在之前,人們使用了兩步構造。
  • 在允許客戶或第三方提供代碼並拋出錯誤的環境中放棄分層和豐富的錯誤消息,調用代碼的原始編寫者在編寫調用代碼時無法預見並且可能提供空間因為他的返回錯誤代碼範圍。
  • 避免了諸如將指向靜態內存對象的指針返回到FlexLm的作者所做的消息分配失敗之類的黑客攻擊
  • 能夠使用內存分配器將地址返回到內存映射的稀疏文件中。 在這種情況下,當一個人訪問有問題的內存時會發生分配失敗。(好的,目前這只適用於Windows,但是蘋果強迫gnu團隊在G ++編譯器中提供必要的功能。需要來自Linux g ++開發人員的更多壓力來提供這個功能也適合他們)(哎呀 - 這甚至適用於STL)
  • 能夠將這種C風格編碼留在我們身後(忽略返回值)並且必須使用帶有調試可執行文件的調試器來查找在具有子進程和第三方提供的共享庫或執行遠程執行的非平凡環境中失敗的內容
  • 能夠將豐富的錯誤信息返回給調用者,而無需將所有內容轉儲到stderr

他們說他們不使用例外,而不是沒有人應該使用它們。 如果你看一下他們寫的基本原理:

由於Google的大多數現有C ++代碼都不准備處理異常,因此採用生成異常的新代碼相對比較困難。

通常的遺留問題。 :-(


我們根本處理容器拋出的異常,至少在應用程序級代碼中是這樣。

自2008年以來,我一直是使用C ++工作的Google搜索的工程師。我們經常使用STL容器。 我個人不記得曾經追溯到像vector :: push_back()或map :: operator []失敗的單一主要故障或錯誤,我們說“哦,我們必須重寫這段代碼,因為分配可能失敗“或”dang,如果只是我們使用例外,這本來是可以避免的。“ 進程是否會耗盡內存? 是的,但這通常是一個簡單的錯誤(例如,有人向程序添加了一個大的新數據文件,忘了增加RAM分配)或者災難性的失敗,沒有好的方法可以恢復和繼續。 我們的系統已經自動管理和重新啟動作業,以便對具有故障磁盤,宇宙射線等的機器保持穩健,這實際上沒有什麼不同。

據我所知,這裡沒有問題。


我很確定他們的意思是他們不在代碼中使用異常。 如果你檢查了他們的cpplint腳本 ,它會檢查以確保你包含STL容器的正確頭文件(如vector,list等)。


根據問題中概述的假設,只有一種可能性來處理分配失敗:

  • 分配器強制應用程序退出分配失敗。 特別是,這需要cusror分配器。

在此上下文中,索引超出範圍的異常不太有趣,因為應用程序可以確保使用預檢查不會發生這些異常。







stl