8

我正在阅读这个页面http://www.cplusplus.com/doc/tutorial/exceptions.html 它说如果我写 function() throw(); 该函数中不能抛出异常。我尝试在 msvc 2005 中编写 throw()、throw(int)、throw(),但什么也没有。每个都有完全相同的结果。没有。我扔了 int, char*, 另一种类型,它们都以相同的方式被捕获。看起来 throw 根本不影响它。function() throw() 实际上做了什么?

4

5 回答 5

10

有关C++ 异常规范和 Microsoft 实现的详细信息,请参阅本文:

Microsoft Visual C++ 7.1 忽略异常规范,除非它们为空。空异常规范相当于__declspec(nothrow),它们可以帮助编译器减少代码大小。

[...] 如果它看到一个空的异常规范,它将假定您知道自己在做什么,并优化处理异常的机制。如果你的函数无论如何都会抛出 - 好吧,你感到羞耻。仅当您 100% 肯定您的函数不会抛出并且永远不会抛出时,才使用此功能。

于 2009-03-02T22:42:50.010 回答
4

你会发现那个版本的 VC++ 没有强制规范异常。我相信这被记录为与标准的差异。

但是,异常规范通常不是一个好主意。如果程序在符合标准的实现中违反了它们(VS 2005 中的 VC++ 在这种情况下不存在),系统应该会捕获它。这意味着规范不是编译器优化提示,而是强制编译器花费额外的长度,有时会产生次优代码。

有关备受推崇的 Boost 项目不使用异常规范的原因,请参阅Boost 基本原理。这就是 Boost,它是用语言的高级部分做奇怪而有用的事情的典型代表。

于 2009-03-02T23:05:02.093 回答
1

引自 A Pragmatic Look at Exception Specifications

(错误)理解

第二个问题与知道你得到了什么有关。正如许多知名人士(包括 Boost 异常规范基本原理的作者)所说的那样,程序员倾向于使用异常规范,就好像它们的行为方式是程序员想要的,而不是他们实际行为的方式。

以下是许多人认为异常规范所做的事情:

  • 保证函数只会抛出列出的异常(可能没有)。

  • 基于仅抛出列出的异常(可能没有)的知识启用编译器优化。

上述预期再次看似接近正确。

有关完整详细信息,请参阅链接。

于 2011-06-28T20:48:29.860 回答
0

抛出异常是不够的,你需要一个try {} catch()块来捕获异常。如果您没有捕获异常,std::terminate()则会调用并且您的程序会突然退出。花一些时间去看看这个

于 2009-03-02T22:44:55.950 回答
0

投掷规格设计用于两个目的:

  1. 作为接口实现和接口用户之间的契约——你声明可以从你的方法中抛出哪些异常,有些人认为它是接口的一部分。(合同)Ala 检查了 Java 中的异常。

  2. 作为向编译器发出信号的一种方式,它可以应用某些优化,以防无法从方法/过程中抛出异常(设置异常处理会花费一些东西)

抛出未在 throw() 子句中指定的异常是错误的,但是在任何时候都不需要实现来为您验证它。事实上,它甚至无法验证,因为它包含了子程序调用的所有可能的异常。(可能来自其他模块)在单个模块中甚至不可能,因为很容易减少到停止问题:)

于 2009-03-02T23:00:07.207 回答