- ios[meta header]
- class[meta id-type]
- std[meta namespace]
- ios_base[meta class]
namespace std {
// C++03 まで
class ios_base::failure : public exception {
public:
explicit failure(const string& msg);
virtual ~failure(); // 備考を参照
virtual const char* what() const throw();
};
// C++11 から
class ios_base::failure : public system_error {
public:
explicit failure(const string& msg, const error_code& ec = io_errc::stream);
explicit failure(const char* msg, const error_code& ec = io_errc::stream);
};
}- ios_base[link ../ios_base.md]
- exception[link ../../exception/exception.md]
- system_error[link ../../system_error/system_error.md]
- error_code[link ../../system_error/error_code.md]
- io_errc[link ../io_errc.md]
- string[link ../../string/basic_string.md]
ios_base::failure は、ストリームライブラリ内の関数で、ストリームバッファ操作の間に検出したエラーを報告するために、例外として送出される全てのオブジェクトの型の基底クラスとして定義されている。
C++11 からは、エラー内容としてメッセージだけではなく、error_code を指定出来るようになった。
これによって、ストリームの操作で発生したエラーをプログラムから判別することが容易になる。
例えば、C++ 標準規格には、ストリームライブラリ内部で発生したエラーの error_code は io_errc::stream と iostream_category() で、OS レイヤで発生したエラーの error_code は system_category() で例外を送出するのが一般的だろうとの記載がある。
しかし、少なくとも現時点では error_code はあまり有効に機能していないようである。
| 名前 | 説明 | 対応バージョン |
|---|---|---|
(constructor) |
コンストラクタ | |
what |
エラーメッセージの取得 | C++03 まで |
なお、一見 C++11 で what() が無くなっているように見えるが、system_error::what() を継承しているため、メンバ関数自体は使用可能である。
ios_base::failureは、C++11 から基底クラスが変更になっている。
このため、C++03 まででも使用可能とするためには、基底クラスがsystem_errorであることに依存しないようにする必要がある。
なお、C++ 標準規格では、ライブラリの各クラスは基底クラスを直接継承しなくても(間接的に継承していれば)良いことになっている。
このため、C++03 でもexceptionから直接派生していないかもしれないので、注意。
(当然 C++11 でもsystem_errorを直接継承していない可能性がある)- C++03 まではデストラクタが宣言されていたが、例外指定が誤っていたため(基底クラス
exceptionのデストラクタにはthrow()が付いているため、派生クラスにもthrow()が必要)、C++11 では宣言自体が削除された。
- C++98
- Clang: 3.0 [mark verified], 3.1 [mark verified], 3.2 [mark verified], 3.3 [mark verified], 3.4 [mark verified], 3.5.0 [mark verified], 3.6.0 [mark verified], 3.7.0 [mark verified], 3.8.0 [mark verified]
- GCC: 4.3.6 [mark verified], 4.4.7 [mark verified], 4.5.4 [mark verified], 4.6.4 [mark verified], 4.7.3 [mark verified], 4.8.1 [mark verified], 4.8.2 [mark verified], 4.9.0 [mark verified], 4.9.1 [mark verified], 4.9.2 [mark verified], 5.1.0 [mark verified], 5.2.0 [mark verified], 6.0.0 [mark verified]
- ICC: ??
- Visual C++: ??
- GCC は 4.9.x までは C++11 モードでも
system_errorを継承していないので、注意が必要である。 - GCC 5.1.0 以降は現時点では
_GLIBCXX_USE_CXX11_ABIマクロが1の場合(通常のビルドでは1がデフォルト)、C++03 モードでも C++11 モードでもライブラリ内から送出された例外をios_base::failure型ではcatchできない。
exception型であればcatchすることができるが、いずれにせよストリーム系の例外とそれ以外の例外を区別することができなくなってしまう。
したがって、少なくともこの問題が解決されるまでは、_GLIBCXX_USE_CXX11_ABIマクロを0にする他ないだろう。(C++03 モードにおける コンストラクタの事後条件の違いも参照)
なお、_GLIBCXX_USE_CXX11_ABIマクロを0にしてしまうと、4.9.x までと同様、モードにかかわらずsystem_errorを継承しなくなってしまうので、注意すること。 - Clang では、C++03 モードでも
strcmp(what(), msg.c_str()) == 0にはならない。
exceptionsystem_errorio_errciostream_category- N2769 Detailed Reporting for Input/Output Library Errors (Revision 2)
基底クラスの変更を含む C++11 での提案文書 - DR331 bad declaration of destructor for ios_base::failure
デストラクタ宣言削除の Defect Report - Bug 66145 - [5/6 Regression] std::ios_base::failure objects thrown from libstdc++.so use old ABI
GCC 5.1.0 以降でライブラリから送出されたios_base::failureがcatchできない問題のバグレポート