the problem
as of right now, exception support streams terrible. when boost.system library adopted c++11, 1 given impression maybe exceptions improve. change did replace std::exception
std::system_error
. while <system_error>
library on own developers, standard committee , standard library implementors have not taken steps towards using improve exception messages.
to give idea of how terrible is, here's brief summary of goes down:
an error occurs.
setstate
used setbadbit
orfailbit
.clear
calledsetstate
.if exceptions enabled,
clear
throwios_base::failure
.
yes, means errors same useless exception message thrown. specified @ basic_ios
level, derived classes suffer issue. offending quote:
[iostate.flags]/4 effects: if
((state | (rdbuf() ? goodbit : badbit)) & exceptions()) == 0
, returns. otherwise, function throws objectfail
of classbasic_ios::failure
(27.5.3.1.1), constructed implementation-defined argument values.
here's example of "implementation-defined argument values" gives us:
ios_base::clear: unspecified iostream_category error
is there easy fix?
neither boost.filesystem
nor boost.iostreams
replacements <iostream>
. former library portably dealing filesystem (and appear in next revision of c++) while latter has with..sources , sinks. documentation states delegates exceptions ios_base::failure
anyways. boost.filesystem
does provide <boost/filesystem/fstream.hpp>
uses path
instead of const char*
arguments open()
. shows example of how 1 might inherit standard library classes:
template < class chart, class traits = std::char_traits<chart> > class basic_ifstream : public std::basic_ifstream<chart,traits> { private: // disallow copying basic_ifstream(const basic_ifstream&); const basic_ifstream& operator=(const basic_ifstream&); public: basic_ifstream() {} // use 2 signatures, rather 1 signature default second // argument, workaround vc++ 7.1 bug (id vswhidbey 38416) explicit basic_ifstream(const path& p) : std::basic_ifstream<chart,traits>(p.boost_filesystem_c_str, std::ios_base::in) {} basic_ifstream(const path& p, std::ios_base::openmode mode) : std::basic_ifstream<chart,traits>(p.boost_filesystem_c_str, mode) {} void open(const path& p) { std::basic_ifstream<chart,traits>::open(p.boost_filesystem_c_str, std::ios_base::in); } void open(const path& p, std::ios_base::openmode mode) { std::basic_ifstream<chart,traits>::open(p.boost_filesystem_c_str, mode); } virtual ~basic_ifstream() {} };
this neat trick, except since our offending function non-virtual , way in basic_ios
, there's combinatorial explosion of have reimplement:
i suspect entire rewrite needed because replacing clear()
won't enough. stream can fail multiple reasons there's one type of exception thrown. while std::system_error
gives better tools of expressing errors, doesn't if, again, there's no way distinguish source of error.
however i'm not library writer , don't feel taking on task. there other options ones listed?
boost open source project way see there 2 options:
- complain. either write bug report or on mailing list , suggest enhancement or both. if community thinks have point, might take on
- do 1, it. you'll support community. might no library writer, maybe people behind boost not either, until were.
there no magic way fix it, has work.
Comments
Post a Comment