本篇主要内容如下:
异常机制
首先,我们得先审视这个问题背后的一个隐含前提:C 语言真的完全不提供异常处理吗?
严格来说,C 语言虽然没有像 C++ 或 Java 那样内置的 try/catch/throw 异常机制,但你确实可以用标准库中的 setjmp 和 longjmp 来构造出某种“类异常”的行为。
不过,这种做法有明显限制:抛出方和捕获方必须事先约定好协作方式——捕获者需要提前设置好一个跳转点(jmp_buf),并确保这个上下文能传递到可能抛出“异常”的函数中。
C 语言的设计哲学
其次,C 语言从诞生之初就没打算引入异常处理,因为它不符合 C 的核心理念和设计边界。
异常处理通常需要:
这些都会引入不可预测的运行时开销,违背C语言“零成本抽象”(zero-cost abstraction)的原则——即你不用的功能不应带来任何代价。
回溯历史,在 C++ 刚出现时,它甚至被称为“带类的 C”(C with Classes)或“C84”之类的名字。早期很多人以为,C++ 最终会取代 C,成为“新一代 C”。
但事情并没有那样发展。
C++ 带着它的类、异常、更严格的类型系统等特性,逐渐演变成一门与 C 截然不同的语言。而 C 语言则选择坚守自己的定位:保持简洁、贴近硬件、可预测且高效。它只做了适度的标准化和小幅改进,目标是理清已有特性、稳定语言本身,而非不断追加高级抽象。
正因如此,C 从未从 C++ “继承”异常机制;更重要的是,C 社区也从未觉得有必要引入它。
因此,如果你团队纪律严明,并制定了一套严格的编码规范,理论上是可以用 C 实现出一套形似异常处理的机制的。
但……
这终究不是 C 语言的设计哲学。
CException
如何在 C 中模拟异常处理,可以参考:CException
https://github.com/ThrowTheSwitch/CException/tree/master
CException 基于 C 标准库中的 setjmp 和 longjmp 实现。完全兼容标准 C,不依赖任何 C++ 特性。只要目标系统支持这两个函数,这个库几乎无需配置即可使用。它甚至支持多任务环境(例如实时操作系统)。当然,它同样适用于更大的系统。
void functionC(void) { // 做一些事情 if (there_was_a_problem) Throw(ERR_BAD_BREATH); // 由于上面抛出了错误,下面的代码永远不会执行}
“在 C 的约束下,提供最接近异常的实用工具,而不牺牲其灵魂。”
它没有试图把 C 变成 C++,而是尊重 C 的简洁与确定性,仅在必要时引入可控的非局部控制流。对于厌倦了“错误码瀑布”的 C 开发者,CException 是一个优雅而克制的折中方案。
本站是社保查询公益性网站链接,数据来自各地人力资源和社会保障局,具体内容以官网为准。
定期更新查询链接数据 苏ICP备17010502号-11