C++除零异常
有人問這個問題:
Code:try { std::cout << 10/0 << std::endl; } catch(...) { std::cout << "exception" << std::endl; } 這段代碼,永遠不會有機會在屏幕上輸出 exception。為什么? 因為和ada或java不一樣,C++標準沒有把除0錯當成標準異常。上面的代碼原樣放到VC里,我猜測(基于對VC的基本信任,也基于我的懶惰),VC也不會執行07行代碼。VC里要抓這樣的異常,需要采用操作系統的結構化異常。它的代碼需要使用 __try/__except來處理。或者需要在編譯選項上,加上讓C++異常支持SEH(結構化異常處理)的參數。C++之父在談C++語言設計的書(The Design and Evolution of C++)里談到:"low-level events, such as arithmetic overflows and divide by zero, are assumed to be handled by a dedicated lower-level mechanism rather than by exceptions. This enables C++ to match the behaviour of other languages when it comes to arithmetic. It also avoids the problems that occur on heavily pipelined architectures where events such as divide by zero are asynchronous."簡單翻譯一下: “底層的事件,比如計算上的溢出和除0錯,被認為應用有一個同樣底層的機制去處理它們,而不是異常。這讓C++在涉及到算術領域的性能,可以和其它語言競爭。再者,它也避免了當某些事件,比如除0錯是異步的情況下(譯者注:比如在別一個線程里發生)所可能造成的‘管道重重’的架構這一問題。”所以,說起來,和原生數組訪問越界為什么不是一異常并無兩樣,主要還是為了“效率/性能”。對于大多數時候的除法操作,我們會讓它出現除數為0的可能性很小,當你認為有這種可能,就自己檢查吧,然后自己定義一個除0錯的異常。很多C++庫,還是實現了EDivByZero之類異常,但僅限于這個庫里的代碼。它們做了檢查。總結一下:C++為什么抓不到除0錯的“異常”? 答:因為C++標準眼里,除0錯不是一個異常。再進一步:C++編譯器,在編譯除法操作時,沒有為它加上額外的檢查代碼以拋出一個異常;也沒有要求處理不同OS之間對(已經發生的)除0錯的處理。另一個原因是,簡單化,比如如果要判斷除0錯,浮點數如何判斷呢?說到底,在事情發生之前,判斷一下不是更好?
Code:if (b == 0) { cout << "別玩我啦...拿個0當除數?" << std::endl; return -1; } 這樣不是很好?
總結
- 上一篇: 全面解读VTL(虚拟磁带库)
- 下一篇: http://dev.firnow.co