为什么std :: uncaught_exception会改为std :: uncaught_exceptions?

时间:2015-01-02 11:27:03

标签: c++ exception c++17

我刚注意到了

http://en.cppreference.com/w/cpp/error/uncaught_exception

C ++ 17会将std::uncaught_exception()替换为bool,而std::uncaught_exceptions()将返回int

标准的补充说明了这一点:

http://isocpp.org/files/papers/n4259.pdf

它没有提供理由,但确实说

  

[注意:当uncaught_exceptions()> 0,抛出异常即可   导致调用std :: terminate()(15.5.1)。 - 结束说明]

这是奇怪的模糊。

这种变化的原因是什么?在C ++ 17或标准的某个未来版本中是否可以有多个活动异常?

3 个答案:

答案 0 :(得分:22)

介绍此内容的论文是n4152,其中有基本原理(通常归结为"使ScopeGuard工作")

引用,

  

至少自1998年以来在第47周的Guru中记录,它意味着从析构函数传递调用的代码本身可以在堆栈展开期间调用,但是无法正确检测它本身是否实际被作为展开的一部分进行调用。一旦你解除了任何异常,即使有多个活动异常,uncaught_exception一切看起来都在展开。

  

这使用了主要实现中已经存在的信息,其中ScopeGuard的当前实现采用依赖于未记录的编译器功能的非便携代码来使ScopeGuard在“实践中可移植”。此选项建议添加一个新函数来公开编译器中已存在的信息,以便这些用途可以真正移植

PS:以下是使用编译器特定信息如何实现此功能的示例:https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp

对于一个使用它的简单示例,请参阅boost.log&#34; s记录泵&#34; (请参阅boost/log/detail/format.hppboost/log/sources/record_ostream.hpp):如果BOOST_LOG(lg) << foo();没有抛出,foo可以登录它创建的防护对象的析构函数是,如果调用析构函数时飞行中的异常数量不大于调用构造函数时的异常数量。

答案 1 :(得分:-1)

std :: uncaught_exception()仅检测堆栈是否展开。在Herb Sutter的一篇论文中,他指出这并不能可靠地表明存在一个活跃的例外。赫伯认为这几乎是&#34;有用。我遇到的情况确实很模糊,这就是我发布这篇文章的原因。

std :: uncaught_exceptions()被指定为返回活动异常的数量,这实际上很有用。

答案 2 :(得分:-1)

请注意,std :: uncaught_exception()对于debug / loginfo仍然有用。它可以帮助确定异常的起源。但是我在功能上同意,它很无用。