对std :: runtime_error和std :: logic_error感到困惑

Dav*_*ter 45 c++ boost stl exception

我最近看到,logic_error如果命令行输入不可解析,boost program_options库会抛出一个.这挑战了我对logic_errorvs.的假设runtime_error.

我认为逻辑错误(logic_error及其派生类)是由于内部无法遵守程序不变量而导致的问题,通常是以内部API的非法参数形式出现的.从这个意义上讲,它们大部分相当于ASSERT,但意味着在已发布的代码中使用(与ASSERT不同,它通常不会编译成已发布的代码.)它们在调试/测试版本中集成单独的软件组件是不可行的情况下非常有用.或者失败的后果使得向用户提供关于无效不变条件的运行时反馈是很重要的.

类似地,我认为runtime_errors仅由程序员控制之外的运行时条件产生:I/O错误,无效的用户输入等.

但是,program_options显然(主要是?)被用作解析最终用户输入的一种方法,所以在我的心理模型中它肯定应该runtime_error在输入错误的情况下抛出.

我哪里错了?你是否同意异常打字的提升模型?

Jer*_*fin 32

在这种情况下,我认为(至少在大多数情况下)你是对的,这是错误的.该标准描述logic_error为:

类logic_error定义了作为异常引发的对象类型,以报告在程序执行之前可能检测到的错误,例如违反逻辑前置条件或类不变量.

无法解析的命令行参数似乎不太适合.

相比之下,它描述runtime_error为:

类runtime_error定义了作为异常引发的对象类型,以报告仅在程序执行时可检测到的错误.

这似乎更合适.


Vla*_*rus 9

从纯粹的标准角度来看,你是对的.program_options应该抛出派生自runtime_error或者logic_error取决于错误是运行时还是逻辑的类.(我没有查看当前的代码来确定当前异常的这种想法分类).

从实际情况来看,我还没有看到C++代码,使得基于例外是有用的决策logic_errorruntime_error.毕竟,你抛出一个logic_error而不是让断言文件的唯一原因是你想以某种方式尝试恢复,这与从运行时错误的恢复没有什么不同.就个人而言,我认为logic_errorruntime_error相同的方式,在Java中检查的异常-理论上不错,但在实践中没有用处.这意味着,也许,我只能program_options::error从中衍生出来exception.也就是说,当我发现'业余时间'时,每个人都在谈论.

  • 我相信你应该让logic_error去终止程序(以便受害者可以将调试/核心信息发送给开发人员),同时应该捕获runtime_error并报告:"你给了我不可解析的信息,请再试一次". (4认同)

hka*_*ser 6

C++ 0x Standard的当前草案(第19.2节):

1)在这些类中反映的错误模型(即异常类型)中,错误分为两大类:逻辑错误和运行时错误.

2)逻辑错误的显着特征是它们是由程序内部逻辑中的错误引起的.从理论上讲,它们是可以预防的.

3)相比之下,运行时错误是由于超出程序范围的事件.它们不能提前预测.

与其他一个答案中引用的引号一起,这解释了为什么Boost.ProgramOptions会抛出std :: logic_error,以防止由于"程序执行前可能检测到的错误"导致的可预防错误.

  • 我认为“在程序执行之前大概可以检测到错误”的意思是“通过足够仔细地阅读程序源代码可以检测到”。 (2认同)