std::error_code 是发出警告的好方法吗?

Is std::error_code a good way to issue warnings?

我目前正在使用 std::error_code 在出现问题时向 API 的用户提供反馈。添加 warning 类型的 std::error_condition 来通知我的用户存在一个小问题但操作会继续,这在语义上是否可以接受?或者我应该只为此使用日志记录吗?

库有多种选项可以告诉用户出现问题或不符合函数调用的预期。

  • 例外。但是有异常开销,try/catch...
  • boost/std::可选。如果有一个 error/warning 你可以将它作为一个 return 值发布(in/out 或输出参数),否则可选的将为 false
  • std::pair/std::元组。这样你就可以在 return 值中编码更多信息(尽管自定义结构也可以更明确地做到这一点)

您可以引入自己的错误数据结构(不要使用 std::error_code,因为它依赖于 OS)。

从库中终止应用程序也不是很实用。即使是库中不可恢复的错误,对实际调用也不会有太大影响application/process/whatever。让来电者决定要做什么。

但这一切并不普遍适用。错误处理没有万能的解决方案。它可能非常特定于 where/how/when 您使用的库,因此您想检查什么适合您的目的以及调用约束 must/should 的强度。

在所有情况下,请清楚调用者对您的错误处理有何期望,不要让它感觉像火箭科学。在我看来,极简设计在这里很有帮助。

如果我没听错,你是在问 return 发出警告是否应该被视为滥用 std::error_code 语义。

现在,标准引入 error_code 作为 标准诊断库的一部分

[diagnostics.general] This Clause describes components that C++ programs may use to detect and report error conditions.

而且,据我所知,对 "error condition" 是什么没有语义要求,我们可以假设这些将用于报告 某事 出错了,但它似乎并没有强加部分实现操作规范的效果应该是什么,操作应该告诉你。

我看到的唯一语义要求是 error_code(和 error_condition)是布尔值可转换的,也就是说,'zero' 错误代码应始终表示成功。

现在,假设您希望一个操作完成并带有警告被认为是成功的,因此 我认为 return 这种通过错误代码发出的警告是无效的; 也就是说,您可能总是让您的操作 return 两个 错误代码(以您喜欢的方式,可能属于不同的类别),记录只有第一个报告实现运行效果:

auto [err,war] = some_operation();

if(err) call_the police(); // some_operation failed
else if(war) // some_operation complains
{
  std::cerr << "hold breath...";

  if( war == some_error_condition )
    thats_unacceptable();

  //else ignore
}

也就是说,请注意,存在与我上面的推理不同的实际用例;事实上,像 HTTP 结果代码和库(如 Vulkan)之类的东西确实使用非零 'result codes' 来表示成功或部分成功的条件 ...

此外,here 诊断库的作者之一都声称 "the facility uses a convention where zero means success." 并同时使用 error_code为 HTTP 错误建模(200包含状态代码)。

这对 error_code::operator bool() 的实际语义(标准中未明确规定其含义)或标准诊断库对错误代码概念建模的有效能力提出了一些疑问以一般方式。 YMMV.