为什么编译器检查C ++中的exception?

C ++提供了检查exception的语法,例如:

void G() throw(Exception); void f() throw(); 

但是,Visual C ++编译器不检查它们; 抛标志简单地被忽略。 在我看来,这使得exceptionfunction无法使用。 所以我的问题是: 有没有办法让编译器检查exception是否正确捕获/ rethrown? 例如一个Visual C ++插件或一个不同的C ++编译器。

PS。 我希望编译器检查exception是否被正确捕捉,否则最终会出现这样的情况: 即使明确声明不会抛出任何东西 ,也不得不绕过每个函数调用。

更新:当使用throw()标记函数时,Visual C ++编译器会显示警告。 这很好,但遗憾的是,当你调用一个可能抛出的子程序时,这个警告不会显示出来。 例如:

 void f() throw(int) { throw int(13); } void h() throw() { g(); } //no warning here! 

在C ++中exception规范是没用的。

没有强制执行其他exception,只是全局函数unexpected()会被调用(可以设置)

使用exception规范主要归结为欺骗自己(或你的同事)成为一种虚假的安全感。 最好不要干扰。

有趣的是,Java已经检查了exception,Java程序员也讨厌这些exception。

C ++中的exception规范是无用的,原因有三:

1. C ++exception规范禁止优化。

除了throw()之外,编译器会插入额外的代码来检查当你抛出一个exception时,它在堆栈展开期间匹配函数的exception说明。 让你的程序变慢的方法。

2. C ++exception规范不是编译器强制的

就你的编译器而言,下面的语法是正确的:

 void AStupidFunction() throw() { throw 42; } 

更糟糕的是,如果违反了exception规范,没有什么用处。 你的程序只是终止!

3. C ++exception规范是函数签名的一部分。

如果你有一个虚拟函数的基类,并试图覆盖它,exception规范必须完全匹配。 所以,你最好提前计划,这仍然是一个痛苦。

 struct A { virtual int value() const throw() {return 10;} } struct B : public A { virtual int value() const {return functionThatCanThrow();} // ERROR! } 

例外规范给你提供这些问题,并且使用它们的收益是最小的。 相反,如果完全避免exception规范,则编码更容易,而且避免了这种情况。

看看这个:

http://www.gotw.ca/publications/mill22.htm

基本的exception规范是不可行的/不可用的,但是这并不能使exception行不通。

至于你的问题,没有办法让编译器检查每一个抛出的types都被捕获在代码中的更高的地方,我期望编译单元使这个困难,这是不可能的代码打算在库中使用(在编译时顶层不可用)。 如果你想确保一切都被捕获,然后在你的代码最上面贴一个catch(…)。

要检测运行时之前的情况下,如…

 extern void f() throw (class Mystery); void g() throw() { f() ; } 

…你需要静态分析 。 是的,编译器正在做大量的静态分析,但是因为标准是“如果throw不匹配会引发std :: unexpected”,写一个抛出一个不符合说明符的对象的例程是完全合法的,编译器实现既不警告也不评论。

声称提供警告服务的静态分析工具包括Gimpel Software 针对C ++的皮棉

1560未捕获exception“名称”不在函数“符号”的throw-list上

并根据这个问题的答案 , QA C ++ 。

因为标准是这样说的。 exception声明并不意味着不会抛出其他exception。 这意味着如果抛出一个未声明的exception,将会调用一个名为unexpected()的特殊全局函数,该函数默认终止程序。 通常在函数中声明exception是不鼓励的(可能除了空的exception列表),因为标准的行为不是很有帮助。

我无法检查这是否缺乏MSVC安装,但你真的确定编译器忽略throw()规范?

这MSDN页面build议微软知道throw(),并期望他们的编译器正确处理它。 那么,几乎可以看到有关他们如何脱离ANSI / ISO标准的说明。

编辑:虽然,在实践中,我同意帕特里克:exception规格大多是无用的。