0

0

c++的错误码(error code)和异常(exception)该如何抉择? (Herb Sutter的观点)

尼克

尼克

发布时间:2026-01-29 14:23:53

|

582人浏览过

|

来源于php中文网

原创

错误码适用于系统级、性能敏感或无法抛异常的场景(如C接口、中断处理、嵌入式裸机);异常适用于现代C++应用逻辑,更安全、易组合、能准确表达“真正意外”。

c++的错误码(error code)和异常(exception)该如何抉择? (herb sutter的观点)

错误码适合系统级、性能敏感或无法抛异常的上下文(如 C 接口、中断处理、嵌入式裸机);异常适合绝大多数现代 C++ 应用逻辑,它更安全、更易组合、更能表达“真正意外”的语义——这正是 Herb Sutter 在 GotW #91 和 C++ 委员会讨论中反复强调的立场。

什么时候必须用 error code?

当调用中存在无法捕获异常的边界时,error_code 或整型错误码是唯一选择:

  • C ABI 兼容接口(如导出给 Python 或 Rust 调用的函数),extern "C" 函数不能抛异常
  • 信号处理函数(signal handler)、中断服务例程(ISR),异常机制在这些上下文中未定义行为
  • 内存极度受限环境(如某些嵌入式 RTOS),禁用异常运行时(-fno-exceptions)后,std::error_codestd::expected(C++23)成为替代方案
  • 需要精确控制错误传播路径(例如:逐层检查并记录每个子操作的 errno),而异常会跳过中间栈帧

为什么异常在应用层更可靠?

Herb Sutter 指出,用错误码“手动传播”极易遗漏检查,而异常强制你面对错误——不是靠约定,而是靠语言机制:

  • 忘记检查 if (fd == -1) 是静默 bug;未捕获异常则程序终止(可配 std::set_terminate),问题立刻暴露
  • 异常支持资源自动释放(RAII),即使多层嵌套调用也能保证 std::unique_ptr、锁、文件句柄被析构;错误码需手动写 goto cleanup 或重复 if,易出错
  • std::exception_ptrstd::nested_exception 可跨线程传递错误上下文;错误码只能传数字,丢失类型、消息、堆栈线索

std::error_code 不是异常的“轻量替代”,而是协作桥梁

Herb 明确反对把 std::error_code& 当作“不抛异常的异常”来滥用。它的设计目标是与系统 API 互操作,不是替代 throw

立即学习C++免费学习笔记(深入)”;

  • std::error_code 本身不带堆栈、不支持动态多态;std::system_error 才是它的异常封装,该抛时就该抛
  • 标准库 I/O(如 std::ifstream::open())默认抛异常;但提供 std::ios_base::failbit + clear() 模式供 error-code 用户切换——这是分层设计,不是二选一
  • 混合使用时,推荐:底层系统调用返回 error_code,上层业务逻辑将其转为具名异常(如 throw std::filesystem::filesystem_error(...)
// 正确协作:将 error_code 转为语义化异常
void open_config_file(const std::string& path) {
    std::error_code ec;
    std::ifstream f{path, std::ios::in | std::ios::binary};
    if (!f.good()) {
        std::filesystem::status(path, ec); // 系统调用返回 ec
        if (ec) {
            throw std::filesystem::filesystem_error(
                "cannot open config", path, ec
            );
        }
        throw std::runtime_error("config file empty or invalid");
    }
}

真正难的是界定“意外”——网络超时是意外还是预期分支?Herb 的建议很实在:如果这个错误在绝大多数调用中都不该发生,且调用方无法合理恢复,就该用异常;如果它是常规控制流的一部分(比如“键不存在”之于哈希查找),std::optionalstd::expected 更贴切。别让错误处理逻辑模糊了业务意图。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++系统编程内存管理_C++系统编程怎么与Rust竞争内存安全
C++系统编程内存管理_C++系统编程怎么与Rust竞争内存安全

C++系统编程中的内存管理是指 对程序运行时内存的申请、使用和释放进行精细控制的机制,涵盖了栈、堆、静态区等不同区域,开发者需要通过new/delete、智能指针或内存池等方式管理动态内存,以避免内存泄漏、野指针等问题,确保程序高效稳定运行。它核心在于开发者对低层内存有完全控制权,带来灵活性,但也伴随高责任,是C++性能优化的关键。

10

2025.12.22

if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

778

2023.08.22

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

15

2025.11.27

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

297

2023.10.25

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

297

2023.10.25

go语言goto的用法
go语言goto的用法

本专题整合了go语言goto的用法,阅读专题下面的文章了解更多详细内容。

137

2025.09.05

clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

1

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.4万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号