我正在读这个:
http://www.cplusplus.com/reference/cstdlib/atoi/
当我看到两句对我来说毫无意义的句子。
这个函数永远不会抛出异常。
VS
如果str没有指向有效的C字符串,或者转换后的值超出了int可表示的值范围,则会导致未定义的行为。
如果错误解析的行为未定义,那么这并不意味着所有赌注都已关闭,并且完全有可能引发异常?或者这是否意味着"未定义,除了运行时承诺不抛出异常"?
答案 0 :(得分:3)
当C或C ++标准谈到未定义的行为时,它们意味着运行程序作为整体的结果是未定义的,而不是未指定执行特定构造的结果或结果。甚至可能在执行错误构造之前将程序的执行脱轨。例如,运行时可以检测到稍后将提供给atoi
的指针是无效的,并且在该点处中断执行。如果编译器可以证明这将发生,它甚至可能无法编译程序。标准明确地对可能导致未定义行为的程序执行结果的内容没有限制。
话虽如此,使用无效参数调用atoi
不太可能引发异常。整数溢出的最可能后果是截断,钳位或陷阱/信号(这不是例外);无效指针的最可能后果是段错误(在类Unix系统上)是一个信号;如上所述,信号不是例外。
尽管如此,给定的实现可能会在收到由segfault或整数溢出产生的信号时选择引发异常并非不可能。这样的实现可能会尝试确保可以捕获如此引发的异常,即使在执行声明为不抛出的函数期间引发了信号。 (这样的实现可能还会记录在这种情况下会引发哪个异常,因为实现可以自由地定义标准未定义的行为的结果。)如果该尝试失败,则异常在异常堆栈中被更高的处罚超出预期,仍然完全缺乏标准规范;可能被指责的最糟糕的情况是未能实施自己对标准的扩展,这是一个实施质量问题。
强制性标准报价:(§1.9 [intro.execution] ,第5段)
执行格式良好的程序的符合实现应该产生与具有相同程序和相同输入的抽象机的相应实例的可能执行之一相同的可观察行为。但是,如果任何此类执行包含未定义的操作,则此国际标准不要求使用该输入执行该程序的实现(甚至不考虑第一个未定义操作之前的操作)。
标准所做的程序执行的任何描述(例如,“不应抛出异常”)都需要在该段的上下文中进行解释。
答案 1 :(得分:1)
C ++标准将术语“未定义”定义为(实际上)意味着C ++标准不会对发生的事情施加任何约束。
函数不抛出异常的语句意味着函数的规范不包括抛出任何异常。
是的,实现者(编译器或标准库的实现)可能会在根据标准未定义的情况下抛出异常。毕竟,如果标准不限制允许发生的事情,则抛出异常是实施者完全可以接受的决定。
但是,这并不意味着未定义行为的实例必须导致抛出异常。它也不意味着抛出的异常表明发生了某些未定义行为的实例。
这确实意味着两个不同的实现(例如,某些供应商的产品的不同版本或来自不同供应商的产品)可以完成不同的事情以响应未定义行为的实例。可以抛出某种形式的例外。另一个可以重新格式化系统硬盘驱动器(幸运的是,故意这样做的实现很少)。因为根据标准未定义行为,所以无论发生什么都是正确的 - 至少根据标准。
答案 2 :(得分:0)
当它说它没有抛出异常时,你应该读到 - 不要指望在出现问题时引发异常。
当然,纯粹的运气可能会引发异常,但不太可能发生。你不应该依赖它。
答案 3 :(得分:0)
只要将有效指针传递给字符串,所有关于该函数的保证都是有效的。
如果不这样做,可能会发生任何事情,包括抛出异常。
换句话说,关于未指定行为的部分优先于有关常规行为的部分。