问题(Question):
除了使用STL或是第三方函式库,我会特别注意需不需要catch例外以外,自己编写
程式大多都还是用旗标或返回值的方式来处理错误,因为我对什么情况下该使用例
外处理其实没有什么概念。
比方说书上在介绍例外处理的章节,大多都采用除0错误当成范例,但除0错误可
以借由运算前检查除数来避免,为什么会特别为此定义一个例外呢?还有像是
fstream若开档失败,则是借由检查实例来侦测,为什么不抛出std::system_error
来作为表示呢?因为没办法从中抓到一个明确的规律或依据,我不太懂得什么样
的场合或情境,使用例外处理而不是判断旗标或返回值。
请问关于这部分是不是有什么技巧或经验可以请各位先进提点一下呢?
谢谢。
除以 0 会产生 interrupt 那跟 CPU 内的除法器设计有关也有一些浮点除法器会直接除出无限大或 NaN 给你就结案我自己写 library 也不用例外机制而用传回值表示因为我希望他在 C 和 C++ 都能通用
作者:
Lipraxde (Lipraxde)
2021-09-28 00:18:00你说的“例外处理”,指的是 C++ 的 exception,还是指另外写 code 处理?还有“例外”,是哪种类型的例外?
作者:
ddavid (谎言接线生)
2021-09-28 11:33:00对exception的态度其实人人不同,没有统一规则相对比较中庸的说法是你想得到的错误就直接检查,想不到的就留给例外去抓,但即便如此还是很模糊比如硬盘坏轨,这是一种可以预想到的错误,但你不可能为了想得到这个发生机率相对低的状况,就在所有读写前面都加上坏轨检测过了才读写另外就是有些语言根本已经把exception内化成一种流程控制手段而非单单的错误处理,所以某些地方用起来只是另一种if,而且“可能”写起来比较简单,这又是另一种状况了
大哉问 我觉得是没办法回复的错误 用例外处理剩下可以回复 或是可以回传错误传值给使用者的用C的错误处理 这是我的习惯 也许别人不是这样
作者:
ddavid (谎言接线生)
2021-09-28 14:20:00我是比较不会用能否回复来做为区分,自己的基本概念是预防与治疗,你事先写好的判断就是预防它发生或者发生了也不会造成问题,所以反而不会有恢复行为。比如事前判断除以零会出错,所以提早发现0,直接不除,所以预防了事情直接发生治疗则是事情让它发生了,事前没有预料、或者就算预料到也无法不让它发生,所以只好让它发生后做一些治疗方案,看要尽可能继续跑或至少留些log再死所以我的区分标准比较像是“你能否阻止它发生”但是因为某些便利性或者语言特性(如Python),我其实也没这么遵守这概念就是,还是很弹性去处理这问题XD
作者:
ddavid (谎言接线生)
2021-09-28 17:01:00Python也是啊,连基本的for loop行为就是一直callnext()直到iterator丢出StopIteration exception而中断Python也有不少基本跟常用package根本上就完全使用例外来回应所有正常完成以外的状态,完全让你被迫使用我抱持上面讲到的概念刚从C/C++转而接触到Python想说“靠,怎么满地都是exception强迫使用啊?”结果现在也是用爽爽了XD
我也有类似的疑惑,CppCon有类似的主题在说我自己理解是对于pre/postcondition用类assert的机制针对逻辑上的失败,可以用expected这种方式可能会发生但也不知道怎么处理(OOM)的就用exceptionHerb有提议新的exception机制,感觉Rust做法和他很像里面提到因例外发生时效率差太多,所以社群主流都不使用前面说的针对逻辑上的失败描述不太好,应该说像是开档或是把字串变成数字这种任务,通常不会希望因非法字串就丢个例外让人处理,因为业务逻辑上本身很有可能发生
作者: ArdenCho (Arden) 2021-09-28 22:57:00
可以使用 try catch 的语法来进行错误例外处理,会比使用 if 还方便许多,而且有些状况是完全没办法使用判断式来进行错误处理的。 但像您的状况,也可以在执行除法之前先检查除数。
作者: shibin (喜饼) 2021-09-28 23:25:00
我是写utility很习惯会throw,却不知道catch后怎么处理好已检查出某些状况会导致后续动作无法正常执行 就可以throw
一般是会用前者 不过理由跟你想探讨的错误处理无关XD
作者: longlongint (华哥尔) 2021-10-01 00:04:00
我是写android 程式才有感觉。可是这里是C板XD底层太抽象+错误资讯跟回传值想分离的时候好用