std::uncaught_exception, std::uncaught_exceptions
ja.cppreference.net から
| ヘッダで定義 <exception>
|
||
bool uncaught_exception() throw();
|
(1) | (C++11 まで) |
bool uncaught_exception() noexcept;
|
(C++11 から) (C++17 で非推奨) (C++20 で削除) |
|
int uncaught_exceptions() noexcept;
|
(2) | (C++17 から) (C++26 から constexpr) |
1) 現在のスレッドに生存している例外オブジェクトがあるかどうか、つまり、例外がスローまたは再スローされ、まだ一致する catch 節に入っていないかどうかを検出します。std::terminate または std::unexpected。言い換えると、
std::uncaught_exception は スタックの巻き戻し が進行中かどうかを検出します。2) 現在のスレッドでスローまたは再スローされ、まだ一致する catch 節に入っていない例外の数を検出します。
例外がスローされていても、場合によっては例外をスローしても安全です std::uncaught_exception() == true(C++17 まで) std::uncaught_exceptions() > 0(C++17 から)。例えば、スタックの巻き戻し が原因でオブジェクトが破棄される場合、そのオブジェクトのデストラクタは、例外がデストラクタを脱出する前にいずれかの catch ブロックで捕捉される限り、例外をスローするコードを実行できます。
戻り値
1)
true このスレッドでスタックの巻き戻しが進行中であれば false、そうでなければ。2) 現在のスレッド内のキャッチされていない例外オブジェクトの数。
ノート
int を返す uncaught_exceptions が使用される例として、boost.log ライブラリがあります。つまり、式 BOOST_LOG(logger) << foo(); はまずガードオブジェクトを作成し、そのコンストラクタでキャッチされていない例外の数を記録します。出力はガードオブジェクトのデストラクタによって実行されます。ただし、foo() がスローする場合は除きます (その場合、デストラクタ内のキャッチされていない例外の数はコンストラクタが観測した数よりも多くなります)。
std::experimental::scope_fail と std::experimental::scope_success は LFTS v3 で、uncaught_exceptions の機能に依存しています。なぜなら、それらのデストラクタはスタックの巻き戻し中に呼び出されるかどうかに応じて異なることを行う必要があるからです。
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_uncaught_exceptions |
201411L |
(C++17) | std::uncaught_exceptions
|
__cpp_lib_constexpr_exceptions |
202411L |
(C++26) | constexpr 例外型用
|
例
このコードを実行
#include <exception>
#include <iostream>
#include <stdexcept>
struct Foo
{
char id{'?'};
int count = std::uncaught_exceptions();
~Foo()
{
count == std::uncaught_exceptions()
? std::cout << id << ".~Foo() called normally\n"
: std::cout << id << ".~Foo() called during stack unwinding\n";
}
};
int main()
{
Foo f{'f'};
try
{
Foo g{'g'};
std::cout << "Exception thrown\n";
throw std::runtime_error("test exception");
}
catch (const std::exception& e)
{
std::cout << "Exception caught: " << e.what() << '\n';
}
}
出力例:
Exception thrown
g.~Foo() called during stack unwinding
Exception caught: test exception
f.~Foo() called normally
欠陥報告
以下の動作を変更する欠陥報告が過去に公開された C++ 標準に遡って適用されました。
| DR | 適用先 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 70 | C++98 | の例外仕様がuncaught_exception() 欠落していた |
として指定されたthrow()
|
関連項目
| 例外処理に失敗したときに呼び出される関数 (関数) | |
(C++11) |
例外オブジェクトを扱うための共有ポインタ型 (typedef) |
(C++11) |
現在の例外を std::exception_ptr (関数) |
外部リンク
| 1. | GOTW 第47号: Uncaught Exceptions |
| 2. | の根拠 std::uncaught_exceptions (N4125) |