Boost ASIO非异常重载函数返回error_code的原因问询
关于Boost ASIO非异常版本API同时通过参数和返回值传递错误码的疑问
Boost ASIO 的 API 通常提供异常抛出与非异常两种重载形式,例如:
void close(); boost::system::error_code close( boost::system::error_code & ec);
或者:
void shutdown( shutdown_type what); boost::system::error_code shutdown( shutdown_type what, boost::system::error_code & ec);
这里有个疑问:为什么非异常版本的函数,既通过传入的 boost::system::error_code& 参数传递错误信息,又要返回一个同类型的错误码?而且从官方示例来看,这个返回值通常会被忽略。
补充更新:不同版本的 Boost ASIO 存在 API 差异——按文档描述,现代版本的非异常 API 理论上应返回 void,但在 Ubuntu 24.04 所使用的 Boost ASIO v1.83 中,这类函数依然返回错误码。例如:
在 /usr/include/boost/asio/detail/reactive_socket_service.hpp 中的实现:
// Disable sends or receives on the socket. boost::system::error_code shutdown(base_implementation_type& impl, socket_base::shutdown_type what, boost::system::error_code& ec) { socket_ops::shutdown(impl.socket_, what, ec); BOOST_ASIO_ERROR_LOCATION(ec); return ec; }
以及 /usr/include/boost/asio/detail/win_iocp_socket_service.hpp 中的实现:
// Disable sends or receives on the socket. boost::system::error_code shutdown(base_implementation_type& impl, socket_base::shutdown_type what, boost::system::error_code& ec) { socket_ops::shutdown(impl.socket_, what, ec); return ec; }
设计原因分析
这种看似冗余的设计主要源于以下几点:
- 历史兼容性:早期 Boost ASIO 的非异常 API 设计就是以返回
error_code的方式传递错误。后续官方虽考虑调整为仅通过参数传递(返回void),但为了不破坏大量依赖旧写法的现有项目,只能保留返回值的兼容设计,避免编译错误。 - 接口灵活性:给开发者提供两种错误处理的选择——你可以提前创建并复用
error_code对象传入(减少重复构造的开销),也可以直接使用返回值快速判断错误,比如:if (auto ec = socket.shutdown(boost::asio::socket_base::shutdown_both, ec)) { // 处理错误逻辑 } - 实现简洁性:从代码实现角度看,函数内部已经需要将错误信息写入传入的
ec参数,直接返回它无需额外逻辑,写法更简洁,减少了代码冗余。
内容的提问来源于stack exchange,提问作者Gluttton
相关产品推荐
相关产品推荐

