[问题] 纯C下的异常处理

楼主: icetofux   2019-11-25 00:19:03
开发平台(Platform): (Ex: Win10, Linux, ...)

编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)

额外使用到的函数库(Library Used): (Ex: OpenGL, ...)

问题(Question):
因为工作上的限制,我目前都在纯C下进行程式开发,编译器可相容于C99。
最近错误处理的问题让我十分在意,一直在想有没有办法可以处理得更好、更为简洁
所以想向各位先进请益。另外这问题其实不算是C/C++专有的问题,但考量到各语言
有不同的语法、处理技巧,我尤其希望能得到C语言上的解答,所以贴在这个版,若
版主觉得不适合或还是觉得有违板规,我会再进行修正或删除。
用个简单的范例来说明,我设计一个程式,当使用者点下按钮时,将系统目前的日期
时间透过通讯发送给远端设备,我将程式拆分为三个部分:
业务逻辑层->协议处理层->硬件驱动层
业务逻辑处理一些程式运作的主流程:当使用者按下UI上的按钮,会取得目前系统时
间,并呼叫协议处理层提供的发送函式(比方说SendTime(...))。
协议处理层负责将收到的时间转换为特定的编码方式,比方说将年、月、日、时、分
、秒各自转换为长度1-byte的资料,并依序排列成一个阵列,接着呼叫硬件驱动层提
供的发送函式(比如说SendData(...))。
硬件驱动实际处理了将资料发送出去的底层行为,这部分大多是呼叫系统提供的底层
API,或是在没有OS的情况下直接进行暂存器操作。
我的问题在于,假设这三层所提供的函式中,都会有失败的风险,最常见到的处理方
式就是在每个函式都加个回传值来确认执行结果,比方说成功传True、失败传False,
或是成功传0、失败有个return code之类的。这里产生几个我觉得疑惑的地方:
1.每次呼叫函式时都要加个if检查式,写到后面发现检查跟业务逻辑用的code数量几
乎是1:1,阅读code时总会觉得业务逻辑跟检查逻辑混在一起有点难阅读,请问这
只需要去适应就好,好是有更好的方式可以处理呢?
2.我在三个层失败的时候都会留下log,可是每当发生错误时回去读log总觉得很冗余
,比方说一但有个硬件异常引起的错误,我会在log中依序看到硬件驱动层的错误讯
息、协议处理层的错误讯息、业务逻辑层的错误讯息。但其实仔细想想硬件驱动层
一但失败其他两个层根本不可能会成功,这增加除错时阅读的难度,而且实质上浪
费了系统资源(内存、储存媒体空间之类的),请问这部分有更好的取舍方式吗?
我不确定有没有把自己疑惑的地方好好表达清楚,如果有语意不明的地方请让我知道。
谢谢。
喂入的资料(Input):

预期的正确结果(Expected Output):

错误结果(Wrong Output):

程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)

补充说明(Supplement):
作者: Schottky (顺风相送)   2019-11-25 00:51:00
这是个很值得探讨的问题,但我这阵子暂时没空回文细说C 没有 try-catch 因此错误处理确实要自己做不少事第一个问题可以用 macro 包装固定的错误检查程序第二个没问题,其实出错时你会想知道 call stack底层出错时偶尔会想知道上层是哪只猪居然这样呼叫如果要集缩成一行也可以,就把错误讯息一路往上传到最上层(你这边是业务逻辑层)才写log,每一层再各自加上自己的姓名和见解,就形成了一个完整的 call stack
作者: Ryspon (Ry)   2019-11-25 02:08:00
好奇推
作者: CodingMan (程式侠)   2019-11-25 08:44:00
我也想知道
作者: chuegou (chuegou)   2019-11-25 09:35:00
关注
作者: F04E (Fujitsu)   2019-11-25 10:10:00
我自己实务上也是采用Schottky的作法
作者: flysonics (飞音)   2019-11-25 11:07:00
和Schottky相似+1不过我的习惯是写一个handler去接所有检查逻辑fail的情况 这样顺带可以从handler function下列清单 一目了然看到自己埋了哪些检查点log的部分 我是会整个Task全部用一个structure去管万一底层发生问题时 只要直接将必要资讯记在structure上 到最上层时再assert卡下来没有try&catch 就自己兜个堪用的方便debug的概念
作者: Qbsuran (Qbsuran)   2019-11-25 15:46:00
wireshark有实作出try-catch(纯C) 可以看看source
作者: eye5002003 (下一夜)   2019-11-25 18:21:00
我很懒惰,所以都是抓__FILE__跟__LINE__喷一下位置出问题的时候才来认真嵌讯息调查
作者: alan23273850   2019-11-26 10:31:00
我怎么记得c++有支援try-catch
作者: ko27tye (好滋好滋)   2019-11-26 14:27:00
c++有阿 标题问的是C
作者: x246libra (楓)   2019-11-28 20:44:00
go的错误处理跟C有点像似 要参考一下吗https://juejin.im/post/5d772620e51d4561c83e7cd2跳到 Opaque errors 来看
作者: exeex (执行档EX)   2019-12-01 14:12:00
做起来应该跟golang有87%像不过golang可以return两个以上的变量包含err, C要另外想办法用macro把return包住是一个方法
作者: flysonics (飞音)   2019-12-02 15:24:00
用macro把return包住 这样会让后面读code的人困扰吧...你包了个一格洞在里面谁知道
作者: dou0228 (7777)   2019-12-05 17:10:00
wireshark exception + zlog, 不要用 __FILE__

Links booklink

Contact Us: admin [ a t ] ucptt.com