在C++11中,这已经被弃用:
void foo() throw();
并被替换为
void foo() noexcept;
在这篇文章中解释了其中一个原因(还有其他原因,归结为同一件事情),即:
虽然我觉得这很有道理,但我不明白为什么首先要动态检查C++异常规范在运行时而不是编译时进行检查,因此它们不能向程序员提供所有异常都已处理的保证。
throw()
,或者为什么noexcept
除了调用std::terminate
而不是正常的堆栈展开之外没有提供异常保证(在我看来这并不是一个可靠的保证)。难道不能在编译期间检查是否抛出异常,如果发生异常则编译失败吗?就我所见,基本上有三种情况:
void foo() noexcept
{
// 1. Trivial case
throw myexcept();
// 2. Try-catch case
// Necessary to check whether myexcept is derived
// from exception
try
{
throw myexcept();
}
catch(exception const & e)
{}
// 3. Nested function call
// Recursion necessary
bar();
}
使用C++模板时,每个类型都需要实例化,编译应用程序本来就需要很长时间 - 所以为什么不将
noexcept
更改为强制编译器在编译时检查是否抛出异常呢?我唯一看到的困难在于一个函数可能会根据运行时状态抛出或不抛出异常 - 但是在我看来,该函数不应该被允许调用自身
noexcept
。我是否遗漏了什么,或者意图是不增加编译时间,或者对编译器开发人员要求较少?
throw()
是编译器对你的保证。noexcept
是你对编译器的保证。 - Kerrek SBvoid foo() noexcept( true ) { bar(); }
,其中bar()
来自于在引入noexcept
关键字之前创建的库? - lapknoexcept
背后的想法是,在某些平台上,如果一个作用域块创建了一个具有析构函数的变量,并且在该变量处于活动状态时调用可能引发异常的方法,则即使函数正常返回(没有抛出异常),确保析构函数将被调用所需的代码也可能引入重大开销。只有编译器知道不会抛出异常,才能避免开销,而通常编译器知道的唯一方法就是由程序员来说明。 - supercat