通过C中的错误处理

在我之前的文章之后,有人问我有关在C中使用GOTO进行错误处理的问题。

我决定去看一堆C代码库,花了我几乎没有时间就找到了这种方法的一些有趣的例子。

在下面,您可以在SQLite代码库中的随机方法中看到一小部分。
就代码质量,数量,测试的彻底性以及整个项目的质量而言,SQLite被认为是最好的C代码库之一。
因此,我认为这是一个很好的样本候选人。

在这里您可以看到有必要释放一些资源,同时处理错误。
通常使用函数结尾处的清除代码来处理此问题,如果需要,错误子句将跳转到该代码。

数据库同步工具

通过C中的错误处理

请注意,这是
非常
与“ GOTO认为有害”不同。
”该文章谈到了跳转到程序中的任意位置。
C(和所有其他现代语言)限制您仅在自己的方法内跳转。
即使SQLite代码库中的方法很长,也可以很容易地了解那里发生的事情。

这是另一个例子,它要复杂得多。
我从Linux内核代码中获取了它:

通过C中的错误处理

再次,我不得不编辑大量实际起作用的代码,以允许我们查看错误处理行为。
现在您可以看到一些
很多
更复杂。

实际上,这里有多个标签,如果出现错误,它们之间会相互跳动。
例如,如果我们未能分配
cifs_sb
我们跳到

_nls
,然后跳转到
出来。
无法扎根将使我们跳到
out_super
然后落入
out
对于
out_free
,它属于
out_nls
然后跳到
出来。

在SQLite示例和Linux示例中,我们都有两个单独的相关职责。
我们需要进行资源清理,但是这可能会在功能中经历不同的阶段,因此变得很复杂。 鉴于此,我认为GOTO清理是最好的选择。

对于C,libdefer和defer宏,有各种defer样式选项。
但是两者都有一些运行时成本。
我比较喜欢defer宏,但是不适用于MSVC,例如,它需要语言扩展。