void MyFunction(int i)throw();
它只是告诉编译器该函数不会抛出任何异常。
它无法确保该功能什么也没有,是吗?
那么throw()
的用途是什么这是多余的吗?为什么提出这个想法?
答案 0 :(得分:5)
首先,当编译器工作正常时, 强制执行 - 但是在运行时,不是编译时..具有空异常规范的函数不会抛出异常。如果发生了会导致异常转移的事件,则会调用unexpected()
,然后调用abort
。您可以使用set_unexpected
来更改被调用的内容,但是允许执行的所有功能是在中止程序之前添加额外的“东西”(例如清理) - 它不能返回到原始执行路径。
也就是说,至少有一个主要的编译器(VC ++)解析异常规范,但不强制执行它们,尽管它可以使用空的异常规范来稍微改进优化。在这种情况下,未遵循的异常规范可能/确实会导致未定义的行为,而不是必然中止该程序。
答案 1 :(得分:1)
正如你所说,它只是告诉编译器该函数不会抛出任何异常。
当编译器期望可能的异常时,它通常必须以某种特定形式生成代码,这使得效率降低。它还可能必须生成一些额外的“家庭”代码,其唯一目的是在抛出异常时处理异常。
当你告诉编译器这个函数永远不会抛出任何东西时,它使编译器更容易识别所有这些额外的与异常相关的开销是完全没有必要的情况,从而帮助编译器生成更高效的代码。 / p>
请注意,如果在运行时实际上尝试从使用throw()
规范声明的函数中抛出某些内容,则不允许该异常退出该函数。相反,将调用所谓的意外异常处理程序,默认情况下将终止程序。因此,在这种意义上,实际上强制执行throw()
函数不会抛出任何东西。
P.S。由于异常规范主要影响程序的运行时行为,因此通常它们可能没有任何编译时效果。但是,这个特定的异常规范 - 空的throw()
- 实际上是由一些编译器在编译时识别的,并且确实导致生成更高效的代码。有些人(包括我在内)认为空的异常规范是唯一真正值得在现实代码中使用的规范。
答案 2 :(得分:1)
它无法确保该功能什么也没有,是吗?
你快到了。这是一个例外规范。这意味着作为一个实施者,你保证你的客户,这段代码不会抛出异常。但是,这并不会阻止MyFunction
内的某些函数抛出,如果你不处理它们,它们会冒泡并以你不想要的方式导致你/客户的程序。它甚至不意味着你内部没有throw
表达式。
最好避免这样的规范,除非你绝对确定你的代码永远不会抛出 - 除了非常基本的功能之外,这是一种困难。请参阅标准swap
,指针分配等。
这是多余的吗?为什么提出这个想法?
不完全是。正确使用后,它可以帮助编译器进行优化。请参阅this文章。 This文章解释了无投掷背后的历史。
进一步挖掘我在Boost文档中找到了this优秀的文章。必读。阅读有关异常保证的部分。
答案 3 :(得分:0)
说实话,现实世界中的异常规范并没有像原始设计师所设想的那样充足。此外,C ++运行时检查异常规范与Java编译时检查异常规范之间的差异也引发了很多问题。
当前除例外规范的规范是:
主要问题是如果你有一个带有throw规范的方法。然后它使用下面的更改,现在抛出新类型的异常,代码没有警告或问题。但是在运行时如果发生异常(新的那个不在throw规范中),那么你的代码将终止()。对我来说,终止是最后的手段,永远不应该在一个格式良好的程序中发生,我宁愿将堆栈一直放回到主要区域,除非允许更加清晰的退出。