Re: [問題] throw跟return?

看板C_and_CPP作者 (stu)時間11年前 (2013/04/12 12:31), 編輯推噓8(8033)
留言41則, 11人參與, 最新討論串2/2 (看更多)
※ 引述《volleyp (彼德さん)》之銘言: : 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) : 想請問在處理錯誤的時候,會怎麼選擇用throw還是return false ? : 最近在看資料結構的書,裡面的程式碼在判斷式的地方好像都是用throw來處理不合條件 : 的情況。但之前我看其他人寫遊戲的時候會用return false來做處理。蠻好奇這兩種 : 做法的差異在哪邊!麻煩前輩們指教一下,謝謝! 個人是不推薦Exception派的 C++雖然有Exception 但是使用上卻很難安全使用 有幾個問題應該可以提出來討論看看 也許只是我功力還不夠 首先是資源釋放問題 C++沒有GC! 發生例外的時候 會跳出try的區域到catch去 如果沒有使用shared_ptr 那麼成功配置的資源將會無法釋放 因為已經拿不到那些local指標 這不只發生在函數內部 物件創立時也可能發生 比方說配置物件後方的member data時 發生要不到記憶體而丟出例外 建構失敗之後就不會執行解構 結果前面的配置空間就會發生memory leak 這個方面可以參考書籍Efficient C++ 不過我覺得不是每個人都會讀過這本書 再來是程式可讀性 return error code的方式 可以很容易就看出程式撰寫時已經考慮哪些問題 throw exception並不容易看出程式是否思考仔細 而且顯然與別人合作寫程式的時候 需要大家先規範好要丟出什麼樣的東西 用error code反而簡單很多,寫個enum或是define就好 只傳遞問題敘述,但是函數內部的問題,由該函數自己處理 這樣程式會比較內斂一點 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.113.210.62

04/12 13:26, , 1F
推這篇
04/12 13:26, 1F
另外還有一點要補充的 例外機制很難在程式中後期加入 這不能靠重構解決問題 不是資料封裝性的事情而已 還直接影響程式運行邏輯 要就只能在初期就考慮周詳 不然就乾脆不要使用 ※ 編輯: iamstudent 來自: 140.113.210.62 (04/12 13:42)

04/12 14:31, , 2F
04/12 14:31, 2F

04/12 14:32, , 3F
另外ctor沒有回傳值,若再考慮有繼承的情況
04/12 14:32, 3F

04/12 14:32, , 4F
其實很難用error code做處理
04/12 14:32, 4F

04/12 14:47, , 5F
construtor我沒話說,沒辦法用error code
04/12 14:47, 5F

04/12 14:49, , 6F
至於一般函數我覺得還是看不出exception好處
04/12 14:49, 6F

04/12 14:50, , 7F
底層無法處理,丟到外層就能處理的情況,我只想到缺RAM
04/12 14:50, 7F

04/12 14:52, , 8F
一般出錯了,就近解決問題應該比較容易才對吧
04/12 14:52, 8F

04/12 14:53, , 9F
不然外層要知道的細節未免也太多了
04/12 14:53, 9F

04/12 14:53, , 10F
簡單情境:發生錯誤時要寫到log還是直接MessageBox
04/12 14:53, 10F

04/12 14:54, , 11F
這個只有外面知道要怎麼做
04/12 14:54, 11F
※ 編輯: iamstudent 來自: 140.113.210.62 (04/12 14:54)

04/12 14:56, , 12F
需要統一管理處理方式的時候需要這樣作嗎?
04/12 14:56, 12F

04/12 15:00, , 13F
寫library給別人用的時候你不知道他要怎麼處理啊
04/12 15:00, 13F

04/12 15:02, , 14F
另外error code占用回傳值,原本回傳值只能用ref參數
04/12 15:02, 14F

04/12 15:03, , 15F
這很麻煩,寫到最後覺得自己根本在寫assembly
04/12 15:03, 15F
謝謝,這樣我就理解了 我原本的角度是函數撰寫者與使用者都是自己人的情況 所以忽略了撰寫library的情形 由於函數傳回值只有一個 改用ref參數傳回error code 那麼函數的介面會變很醜 看了你推薦的那篇文章之後還瞭解一點 使用error code方式處理 每次呼叫都要作的檢查 會出現很多check處理 我目前有碰過一些C的library 作法是有額外的Check函數 可以在一連串動作之後才檢查error code 而不是每個動作都檢查 也不需要在每個函數上面多出ref傳遞錯誤代碼 函數的參數就可以很乾淨 這樣應該也是一個解法 此外Constructor也有解法 就是Constructor放空 然後多一個Init的成員函數 使用者必須手動初始化 會placement new的人可能覺得很多餘 可是這樣其實很容易被理解 獨立初始化就可以輕易處理error code 不過這樣要配合stl容器就有點頭痛了 裡面有copy constructor...

04/12 15:20, , 16F
推這篇, throw一整個很難處理記憶體問題...
04/12 15:20, 16F

04/12 15:21, , 17F
不過反正還在開發階段時leak就讓他leak算了...
04/12 15:21, 17F
※ 編輯: iamstudent 來自: 140.113.210.62 (04/12 15:33)

04/12 15:32, , 18F
04/12 15:32, 18F

04/12 15:50, , 19F
看到 exception 就要先想到 RAII,然後我的頭就痛了...
04/12 15:50, 19F

04/12 17:45, , 20F
Chikei 那篇滿中肯的
04/12 17:45, 20F

04/12 17:46, , 21F
exception和leak沒有絕對關係,用error code也可能leak
04/12 17:46, 21F

04/12 17:47, , 22F
error code的場合若不用RAII,是會寫出世界奇觀的
04/12 17:47, 22F

04/12 17:48, , 23F
Exception 的程式明明比較簡單易懂... =.=
04/12 17:48, 23F

04/12 17:49, , 24F
不過 C++ 用 Exception 比較麻煩是真的
04/12 17:49, 24F

04/12 17:50, , 25F
Exception 的發明本身就是經過許多有經驗的前人為了解決
04/12 17:50, 25F

04/12 17:50, , 26F
error code 造成的混亂才發明的東西
04/12 17:50, 26F

04/12 18:11, , 27F
剛學directx之類的碰到一堆error check真的很想死XD
04/12 18:11, 27F

04/12 18:12, , 28F
所以有些教學一開始會先忽略掉error check
04/12 18:12, 28F

04/12 18:12, , 29F
然後之後開始error的時候就很想死
04/12 18:12, 29F

04/12 19:03, , 30F
微軟在 CRT 原始碼裡面 (純C語言),沒有 RAII 可以用
04/12 19:03, 30F

04/12 19:04, , 31F
都用 goto 解決。改用 while() 再 break 避開 goto 也行啦
04/12 19:04, 31F

04/12 19:14, , 32F
littleshan的說法好像是對的,error code不搭配RAII
04/12 19:14, 32F

04/12 19:15, , 33F
感覺是建立在new或malloc都不會出問題的假設上
04/12 19:15, 33F

04/12 19:17, , 34F
只有錯誤與配置資源無關時才能不用RAII的樣子
04/12 19:17, 34F

04/12 22:33, , 35F
linux原始碼大量使用error code跟goto,看得很累
04/12 22:33, 35F

04/13 12:29, , 36F
leak跟except是正交的問題,modern c++ 已經完全不推薦自己
04/13 12:29, 36F

04/13 12:30, , 37F
用 raw pointer 管理資源,而且這個轉化跟 exception 無關
04/13 12:30, 37F

04/13 12:30, , 38F
單純只是手動管理太容易出錯,能用 container 的就用contnr
04/13 12:30, 38F

04/13 12:31, , 39F
該用 shared 的就 shared,該 scope/unique 就 scope/uniq
04/13 12:31, 39F

04/13 12:34, , 40F
弄清每個資源的所有權跟生命週期的種類應該是哪種…
04/13 12:34, 40F

04/13 12:35, , 41F
以用正確的包裝,以求最高效能最小的心智負擔才是C++ style
04/13 12:35, 41F
文章代碼(AID): #1HPuuggD (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 2 篇):
文章代碼(AID): #1HPuuggD (C_and_CPP)