2015-01-02 22 views
9

我只注意到了在爲什麼將std :: uncaught_exception更改爲std :: uncaught_exceptions?

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或未來版本的標準中是否可以有多個活動的異常?

+1

在所有版本的C++中都可能存在多個活動異常。 'struct foo {〜foo(){try {throw new int; } catch(...){}}}; int main(){{foo f;拋出新的雙倍; } catch(...){}}當我們銷燬'f'時,''有兩個活動異常。 – Yakk

+1

參見[this CppCon 2015 talk](https://github.com/CppCon/CppCon2015/blob/master/Presentations/Declarative%20Control%20Flow/Declarative%20Control%20Flow%20-%20Andrei%20Alexandrescu%20-% 20CppCon%202015.pdf)由Andrei Alexandrescu提供有關'ScopeGuard'和N4259的信息。 – Adversus

回答

18

介紹了這是n4152紙,它具有合理性(通常歸結爲「使ScopeGuard工作」)

引述,

在大師自1998年以來至少記錄在第47周,它意味着從析構函數傳遞調用的代碼,在堆棧展開期間本身可以調用的代碼無法正確檢測它本身是否實際上是作爲展開的一部分被調用的。一旦您解除任何異常,至uncaught_exception即使存在多個活動異常,一切都看起來像展開。

而且

這種使用已經存在的主要實現方式,其中信息ScopeGuard訴諸依靠無證編譯器的功能,使ScopeGuard「便攜式實踐」今天不可移植的代碼的當前實現。此選項提議增列一個新的功能,以揭露的信息已經存在於的編譯器,使這些應用能夠真正的便攜式

PS:這裏有一個如何這個功能可使用編譯器speicific信息來實現的例子: https://github.com/panaseleus/stack_unwinding/blob/master/boost/exception/uncaught_exception_count.hpp

而對於使用它的一個簡單的例子,那沒有比boost.log的「記錄泵」(見boost/log/detail/format.hppboost/log/sources/record_ostream.hpp):它能夠爲BOOST_LOG(lg) << foo();登錄它創建如果保護對象的析構函數foo不會拋出,也就是說,如果調用析構函數時飛行中的異常數不大於t當構造函數被調用時。

+8

顯示多個活動異常如何存在的示例可能會亮起。 – Yakk

-1

的std :: uncaught_exception()只檢測堆棧是否爲退繞。在Herb Sutter的一篇論文中,他指出,這並不能可靠地表明存在一個活躍的例外。 Herb認爲這「幾乎」有用。我遇到了這種情況,這確實是模棱兩可的,這就是我引起這個職位的原因。

std :: uncaught_exceptions()被指定爲返回活動異常的數量,這實際上是有用的。

-1

請注意,std :: uncaught_exception()對debug/loginfo仍然有用。它可以幫助確定發生異常的位置。不過,我在功能上同意,它相當無用。

相關問題