4

借助指南支持库和gsl_ExpectsC++ 等实用程序,暂时实现了合约(有计划在未来将这些东西融入语言中)。使用此功能并根据您的项目设置,可能会违反合同:

  • 抛出异常或
  • 呼叫终止

我想知道恢复策略应该是什么。显然在第二种情况下(您设置违反合同以调用终止)没有,但即使在第一种情况下也很难恢复;由于异常是某种内部类型(例如,fail_fast源自logic_error旨在供人类读者进行事后分析)。

因此,鉴于所有这些,我的问题是:您是否打算从违反合同的情况中恢复过来?如果是怎么办?有没有描述如何做到这一点的来源?如果不是,将我的错误检查+处理与合同检查分开,只考虑硬错误方面的合同是个好主意吗?

我想第二个选择是我倾向于的,但令人讨厌的是,这些违规行为会导致我的整个程序崩溃,而不是取消单个函数。

我可以像这样构建合同轴承功能:

std::optional<return_t> my_function(Arg arg)
{
  std::optional<return_t> ret;

  try {
    gsl_Expects(...); // do contract checking 
    /* rest of function */
  } catch (fail_fast& e) {
    // report contract violation
  }

  return ret;  // Exceptions from contract violations are turned into empty optional
               // Other exceptions are handled like before (locally or from the caller)
}

但感觉它超出了使用合同的目的。

4

2 回答 2

3

你不应该从合同错误中恢复过来。合约错误是您的程序中的逻辑错误,换句话说,您的程序是错误的。没有合理的方法可以从中恢复,您能做的最好的事情就是杀死并重新启动发生故障的整个子系统,并希望这是一个罕见的故障。

您可以预见的异常情况不应由合约处理,这就是异常机制的用途。

于 2021-07-19T08:29:09.370 回答
2

可能会有一些策略。

假设一个程序显示了一些 UI,用户打开了一些文件,并且由于该文件已损坏,加载数据违反了一些合同。

异常处理不会在恢复文件结构的一致状态方面做一些“恢复”,而是只会破坏文件相关的结构,并报告错误。

这仍然不是“硬”错误。UI 相关的结构是完整的,程序可以继续。

当然,这可能被认为不是很好的做法。理想情况下,所有外部数据都经过验证,因此不存在对不良数据的合同违规,因此合同违规是致命的。不确定您是否正在编写理想的程序。我不。

于 2021-07-19T08:25:44.013 回答