Re: [問題] try catch(...)的問題

看板C_and_CPP作者 (我愛阿蓉)時間14年前 (2011/10/31 15:31), 編輯推噓5(5030)
留言35則, 7人參與, 最新討論串5/5 (看更多)
大家好 因為我能力不足 我去把C++ Primer 3rd的11章讀完 始終有些問題想請教各位 1. Exception Specification (1)我不曉得怎麼表達一個函式如果會thorw超過一種的exception type該怎描述 從他範例我看到一種寫法 我寫void Foo(...) throw(int, double){ thorw 55.66;} 竟然發生unexpected exception..... 不解耶 我throw int就OK 是不是有什麼誤會 另外 (2) 他寫throw();保證函式不會throw exception 所以我試著寫 void Foo(...) {throw 123;} compile OK, Run-time也沒有問題 只不過讓我catch到exception.. 我以為他保證不會throw exception表示compiler在compile time有能力可以把這個寫法 給檢查出來 我觀念似乎有誤 請指正 2. 假如我用了一個一些library 但不小心踩到他內部的bug , 我看不到code也改不了 假如他剛好沒有檢察null pointer就去dereference 造成了exception 為了不讓我程式邏輯錯誤 我希望我能做一些handle 不過看起來是不是沒法可以避免程式當掉 之前再寫C# 就很無腦 任何code都用try{}catch (Exception e){} 包起來 只要有意料之外或我自己邏輯疏忽的exception我通通抓的到 目前我觀念是解釋成 C#他就算是null pointer 去做存取 他內部也會有邏輯檢查null然後轉成exception object throw上來 其他case 如divide by zero阿 index out of range阿 他其實都有做內部檢查 然後再 throw出來 所以我才catch的到? 反觀C++就是沒救 要是別人module寫出問題 我也沒辦法避免程式異常終止發生? 3. 既然exception處理的 成本這麼高, 我全部轉成error code不是比較友善且有效率嗎? 這問題應該有專門的討論或書籍.... 請板友給些線索吧 以上 謝謝各位 ※ 引述《tropical72 (藍影)》之銘言: : ※ 引述《QQ29 (我愛阿蓉)》之銘言: : : try : : { : : 1. throw; //跑到這行就掛了? : : 2. throw exception(); //會進到catch : : 3. int a, b = 0; a= 1/b; //catch不到.... : : 4. int *ptr = 0; *ptr = 5566; //catch 不到 : : } : : catch(...) : : { : : } : 直接看範例比較快。 : try { : unsigned a=1, b=0; : if(b==0) throw "分母為 0" ; : if(b>a) throw "相減溢位" ; : if(b==a) throw "a 等於 b" ; : throw " 正常執行 "; /* 通常這個沒人在寫 */ : } : catch ( char* msg) { : cout << msg << endl; : } : 簡單用法大致上就樣,所以你的 3. 4 : : 3. int a, b = 0; a= 1/b; //catch不到.... : : 4. int *ptr = 0; *ptr = 5566; //catch 不到 : catch 不到,純粹是因為沒有做 throw 動作,那些異常的判斷還是必須要靠 : throw 丟出去,而 throw 後面通常會加一個 「例外物件」 出去,只是這例子的 : 例外物件是 char* 而已,當然丟出去的例外物件可以是 int、可以是 : vector <int> (可能沒人丟這個),甚至有時候會這麼做 : try{ : unsigned a=1, b=2; : if(b==0) throw 0; : if(b>a) throw "相減溢位"; : }catch(int error_no){ : cout << "error no : " << error_no << endl; : }catch(char* error_msg) { : cout << "error msg : " << error_msg << endl; : } : 可以丟出 (throw) 不同資料型態 (類別的話需注意轉形問題) 之例外物件, : 甚至可以只針對其中幾種物件出來處理,而其它的例外物件全都丟到 ... : 裡面處理, 像是這樣 : try{ : unsigned a=1, b=2; : throw 1.0; : if(b==0) throw 0; : if(b>a) throw "相減溢位"; : }catch(int error_no){ : cout << "error no : " << error_no << endl; : }catch(char* error_msg) { : cout << "error msg : " << error_msg << endl; : } : catch(...){ : cout << "nonknow expect!!\n"; : } : 丟出去的例外物件為 double ,不是 int ,也不是 char*,最後由 : catch(...) 全部接收,所以至少可知道一件事: : 一般而言,throw 後面一定會加上一個 例外物件 : 上面這規則註明了「一般而言」,因為有種例外,叫「復拋 (Rethrow)」, : 但復拋之 throw 不會是寫在 try 裡面,而是寫在 catch 裡面, : 說明請詳參 C++ Primer 4e 17.1.4,所以你的第一個 throw 也是錯的。 : 其它的 throw 問題,如解構、有 catch 沒 throw 等,會發生什麼事, : 這些在 Primer 裡面也有提到。 : C++ Primer 異常處理那裡,大致上都寫許多了,可能堅澀些所以沒那麼好懂, : 建議還是要硬著頭皮掃過二遍。另一本書例外處理我倒覺得寫得還蠻不錯的, : The C++ Programming Language , exception handling 那章, : 整章沒提到函式庫裡已有的例外類別,都在探討觀念。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.147.15.66

10/31 15:50, , 1F
不要用 throw( ... ) 來修飾了 ... 它不會像 Java 或
10/31 15:50, 1F

10/31 15:50, , 2F
C# 那樣工作. 你 throw 了其他的 type, 在 C++ 裡只表
10/31 15:50, 2F

10/31 15:52, , 3F
示這是一個嚴重錯誤, 它會呼叫 unexcepted_handler
10/31 15:52, 3F

10/31 15:52, , 4F
這個 handler 是全域且唯一, 所以你只能統一處理各種
10/31 15:52, 4F

10/31 15:53, , 5F
exception, 使用文件來說明會是比較恰當的
10/31 15:53, 5F

10/31 15:55, , 6F
至於第二個問題 ... 嗯, 你可以送 bug report XD
10/31 15:55, 6F

10/31 15:56, , 7F
第三個問題其實也是設計上的選擇問題, error code 可以
10/31 15:56, 7F

10/31 15:57, , 8F
被忽略, 但 exception 則強迫客戶一定要決定處理方式
10/31 15:57, 8F

10/31 16:09, , 9F
l大 可是我throw int就OK耶 為啥double就爆炸 好怪 我VS 2010
10/31 16:09, 9F

10/31 16:10, , 10F
只要程式附加 Debugger 運行,出現任何 Exception 都可以
10/31 16:10, 10F

10/31 16:10, , 11F
被 Debugger 抓到,你根本連寫 try 的必要性都沒有
10/31 16:10, 11F

10/31 16:37, , 12F
第二個問題應該無解吧,如果看不到的func本身在執行出包
10/31 16:37, 12F

10/31 16:37, , 13F
且func本身沒做例外處理,這應抓不出來.
10/31 16:37, 13F

10/31 17:50, , 14F
如果我沒記錯exception spec已經列為deprecated了
10/31 17:50, 14F

10/31 17:58, , 15F
@QQ29 我用 VC10 或 gcc 4.6 都沒問題
10/31 17:58, 15F

10/31 18:10, , 16F
抱歉 我好像寫錯 丟double是OK~ l大妳說不要用 throw(..)修飾
10/31 18:10, 16F

10/31 18:10, , 17F
是什麼意思呢? C++這樣寫不好喔?
10/31 18:10, 17F

10/31 18:10, , 18F
另外有遇到一個compile warning是 C++ exception specificati
10/31 18:10, 18F

10/31 18:11, , 19F
ignored except to indicate a function is not __declspec(
10/31 18:11, 19F

10/31 18:11, , 20F
(nothrow) 不曉得是什麼意思 有人知道該怎麼 改才修得掉嗎
10/31 18:11, 20F

10/31 18:14, , 21F
把你會出現warning的程式碼完整的貼上來看看?
10/31 18:14, 21F

10/31 19:02, , 22F
不要在 C++ 中使用 exception spec 因為它不像 java
10/31 19:02, 22F

10/31 19:03, , 23F
(結果我還是在重覆legnaleurc的推文 orz)
10/31 19:03, 23F

10/31 19:03, , 24F
http://codepad.org/UscehH5Q 很無腦的sample XD
10/31 19:03, 24F

10/31 19:03, , 25F
唯一的例外是使用 throw() 來表示不會丟例外
10/31 19:03, 25F

10/31 19:04, , 26F
所以primer 3rd的這算是資訊老舊了? 不該用嚕
10/31 19:04, 26F

10/31 19:05, , 27F
可是我(2) 故意丟例外 也沒事耶 還是這只是一個提醒使用者
10/31 19:05, 27F

10/31 19:05, , 28F
的意思
10/31 19:05, 28F

10/31 19:08, , 29F
簡單的說, Java 或 C# 是"你不能丟", compiler 會擋
10/31 19:08, 29F

10/31 19:08, , 30F
C++ 是"你可以丟, 但這是嚴重錯誤", compiler 不會擋
10/31 19:08, 30F

10/31 19:08, , 31F
其實我一直不知道C++的exception要怎麼樣才算"正確使用"
10/31 19:08, 31F

10/31 19:48, , 32F
軟體測試的就交給那些測試偵錯的手段,不要用例外處理干涉
10/31 19:48, 32F

10/31 19:48, , 33F
已經知道會有的例外,才將 try 當作可行的解決方案。至於
10/31 19:48, 33F

10/31 19:49, , 34F
語法、用法上的,就多寫多試多撞牆多看別人怎麼用...
10/31 19:49, 34F

10/31 21:07, , 35F
再講下去可能會延伸到 Software testing
10/31 21:07, 35F
文章代碼(AID): #1EhaxdOU (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1EhaxdOU (C_and_CPP)