Namespaces
Variants

Exceptions

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

例外処理は、プログラムの実行中の特定の地点から、その実行が以前に通過した地点に関連付けられたハンドラへ、制御と情報を転送する方法を提供します(言い換えれば、例外処理はコールスタックを遡って制御を転送します)。

throw を評価すると例外がスローされます。例外は 他のコンテキスト でもスローされることがあります。

例外を捕捉するためには、 throw 式が try ブロック 内になければならず、かつ try ブロックには例外オブジェクトの型に一致する ハンドラ が含まれていなければなりません。

関数を宣言する際に、以下の指定を行うことで、関数がスローする可能性のある例外の型を制限することができます:

(C++17まで)
(C++11以降)

例外処理中に発生するエラーは、 std::terminate および std::unexpected (C++17まで) によって処理されます。

目次

翻訳内容: - "Contents" → "目次" - C++関連用語(Usage、Error handling、Exception safety、Exception objects、Notes、External links)は原文のまま保持 - HTMLタグ、属性、数値はすべて変更せず - フォーマットと構造は完全に維持

使用方法

throw 式は、実行スタック上の任意のコードブロックに制御を転送するために使用できますが( std::longjmp と同様)、その本来の使用目的はエラーハンドリングです。

エラーハンドリング

例外をスローすることは関数からのエラーを通知するために使用され、「エラー」は通常以下のものに限定されます [1] [2] [3] :

  1. 事後条件を満たさない失敗。例えば、有効な戻り値オブジェクトを生成できない場合など。
  2. 呼び出す必要がある他の関数の事前条件を満たさない失敗。
  3. (非プライベートメンバー関数の場合) クラス不変条件を(再)確立できない失敗。

特に、これはコンストラクタ( RAII も参照)およびほとんどの演算子の失敗は、例外をスローすることで報告されるべきであることを意味します。

さらに、いわゆる wide contract 関数は、受け入れ不可能な入力に対して例外を使用して通知します。例えば、 std::basic_string::at には事前条件がありませんが、範囲外のインデックスに対して例外をスローします。

例外安全性

関数によってエラー状態が報告された後、プログラムの状態に関して追加の保証が提供される場合があります。一般的に認識されている例外保証のレベルは以下の4つであり、これらは互いに厳密な上位集合となっています: [4] [5] [6]

  1. Nothrow(または nofail)例外保証 — 関数は例外を送出しない。Nothrow(エラーは他の手段で報告されるか隠蔽される)は、 デストラクタ およびスタック巻き戻し中に呼び出される可能性のある他の関数に期待される。 デストラクタ はデフォルトで noexcept である。 (C++11 以降) Nofail(関数は常に成功する)は、swap関数、 ムーブコンストラクタ 、および強い例外保証を提供する関数によって使用される他の関数に期待される。
  2. 強い例外保証 — 関数が例外を送出した場合、プログラムの状態は関数呼び出し直前の状態にロールバックされる(例: std::vector::push_back )。
  3. 基本例外保証 — 関数が例外を送出した場合、プログラムは有効な状態である。リソースリークは発生せず、全てのオブジェクトの不変条件は維持される。
  4. 例外保証なし — 関数が例外を送出した場合、プログラムは有効な状態ではない可能性がある:リソースリーク、メモリ破損、または他の不変条件破壊エラーが発生している可能性がある。

ジェネリックコンポーネントはさらに、 例外中立保証 を提供する場合があります:テンプレートパラメータから例外がスローされた場合(例えば Compare 関数オブジェクトから、または std::sort T のコンストラクタから、あるいは std::make_shared において)、その例外は変更されずに呼び出し元に伝播されます。

例外オブジェクト

完全型のオブジェクトおよびcv修飾された void へのポインタは例外オブジェクトとしてスローできますが、すべての標準ライブラリ関数は無名オブジェクトを値でスローし、それらのオブジェクトの型は(直接的または間接的に) std::exception から派生しています。ユーザー定義例外も通常このパターンに従います。 [7] [8] [9]

例外オブジェクトの不必要なコピーやオブジェクトスライシングを避けるために、ハンドラは参照でキャッチするのがベストプラクティスです。 [10] [11] [12] [13]

注記

機能テストマクロ 規格 機能
__cpp_constexpr_exceptions 202411L (C++26) constexpr 例外

外部リンク

  1. H. Sutter (2004) "例外をいつ、どのように使用するか" Dr. Dobb's 誌
  2. H. Sutter, A. Alexandrescu (2004), "C++ Coding Standards", 項目70
  3. C++ Core Guidelines I.10: 必要なタスクの実行失敗を通知するために例外を使用する
  4. B. Stroustrup (2000), "The C++ Programming Language" 付録E
  5. H. Sutter (2000) "Exceptional C++"
  6. D. Abrahams (2001) "ジェネリックコンポーネントにおける例外安全性"
  7. D. Abrahams (2001) "エラーと例外処理"
  8. isocpp.org Super-FAQ "何をスローすべきか?"
  9. C++ Core Guidelines E.14: 例外として組み込み型ではなく、目的に合わせて設計されたユーザー定義型を使用する
  10. C++ Core Guidelines E.15: 値でスローし、階層からの例外は参照でキャッチする
  11. S. Meyers (1996) "More Effective C++" 項目13
  12. isocpp.org Super-FAQ "何をキャッチすべきか?"
  13. H. Sutter, A. Alexandrescu (2004) "C++ Coding Standards" 項目73