2016-10-25 2 views
5

ここからMWEを実行していました: http://www.cplusplus.com/reference/ios/ios/exceptions/ 私のマシンでは、例外が発生しません。C++を使用して存在しないファイルを開くと例外が検出されない

が 'STD :: ios_base ::失敗'

のインスタンスを投げた後に呼び出さTERMINATEものを():ここで私が取得アーチ-Linux上でgcc 6.2.1を使用して自分のコード

#include <iostream> 
#include <fstream> 

int main() 
{ 
    std::ifstream file; 
    file.exceptions(std::ifstream::failbit | std::ifstream::badbit); 
    try 
    { 
     file.open("IDoNotExist.txt"); 
    } 
    catch(const std::ifstream::failure& e) 
    { 
     std::cout << "Bad luck!" << std::endl; 
    } 
} 

次のとおりです。 basic_ios :: clear

しかし、上に掲載されたリンクでは、コードがファイルのオープンに関連する例外もキャッチする必要があることが記載されています。何が悪かったのか?

+2

これは悪い例のようです。 1つの例外として、例外はあなたのようにconst参照によって捕捉されるべきですが、そうではありません。 – NathanOliver

+0

g ++ 6.2.0をLinux上にインストールした場合、このプログラムは "Bad luck!"を表示します。私はまた、このプログラムが '失敗'例外をキャッチして "Bad luck"を印刷しなければならないことも知っています。 ( 'IDoNotExist.txt'は真に存在しないと仮定します)。したがって、C++コンパイラおよび/またはランタイムが誤動作しています。これの最も一般的な理由は、誤ってインストールされていることです。その名前に 'g ++'や 'C++'を使ってパッケージをアンインストールして再インストールしてみてください。 – zwol

+0

cplusplus.comには肯定的な側面がありますが、否定的な側面もあります(詳しく知りたい場合は、サイトについての意見が分かれています)。私は代わりに[この参照サイト](http://en.cppreference.com/w/cpp)を好む傾向があり、より最新で正確なようです。たとえば、[I/Oストリーム例外](http://en.cppreference.com/w/cpp/io/basic_ios/exceptions)の例では、正しいクラスを使用してキャッチします。 –

答えて

1

known bug in libstdc++のように見えます。

問題は、C++ 11 ABIの変更により、多くのクラスが古いABIを持つlibstdc++6.soに複製され、もう1つは新しいものに複製されたということです。

例外クラスは重複していないため、この時点ではこの問題は存在しませんでした。しかし、新しい言語の一部では、std::ios_base::failurestd::exceptionの代わりにstd::system_errorから得られるはずですが、system_errorはC++ 11のクラスであるため、新しいABIフラグを使用する必要があります。今度は、2種類の異なるstd::ios_base::failureクラスがあり、手間がかかります!

簡単な解決策は、-D_GLIBCXX_USE_CXX11_ABI=0でプログラムをコンパイルし、バグが解決されるまで古いABIに辞めることです。あるいは、catch (std::exception &e)と書きます。

関連する問題