提问人:Lorah Attkins 提问时间:7/19/2021 最后编辑:Lorah Attkins 更新时间:7/21/2021 访问量:247
你是要从违反合同中恢复过来吗?
Are you meant to recover from contract violations?
问:
有了指南支持库和像gsl_Expects
这样的实用程序,C++暂时实现了合约(有计划在未来将这些东西烘焙到语言中)。使用此功能并根据您的项目设置,可能会违反合同:
- 抛出异常或
- 呼叫终止
我想知道恢复策略应该是什么。显然,在第二种情况下(您设置了违反合同以调用终止)中没有,但即使在第一种情况下也很难恢复;由于异常是某种内部类型(例如 这源于 ) 很难构建恢复策略:我应该捕获哪些异常,在哪个级别,是否有有用的信息可以帮助我恢复(我认为 file+line 是为了让人类读者进行事后分析)。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)
}
但感觉它违背了使用合约的目的。
答:
可能有一些策略。
假设一个程序显示一些 UI,用户打开某个文件,并且由于该文件已损坏,加载数据违反了某些协定。
异常处理不会在还原文件结构的一致状态方面进行一些“恢复”,相反,它只会破坏与文件关联的结构,并报告错误。
这仍然不是“硬”错误。与 UI 关联的结构完好无损,程序可以继续。
当然,这可能被认为是不太好的做法。理想情况下,所有外部数据都经过验证,因此不会因不良数据而违反合同,因此违反合同是致命的。不确定你是否在编写理想的程序。我没有。
你不应该从合同错误中恢复过来。合约错误是程序中的逻辑错误,换句话说,程序是错误的。没有合理的方法可以从中恢复,您能做的最好的事情就是杀死并重新启动发生故障的整个子系统,并希望这是一次罕见的故障。
您可以预期的特殊情况不应由合同处理,这就是例外机制的用途。
评论
square root
评论