Re: The C++ article in April issue of DDJ
On Mar 20, 7:03 pm, "ThosRTanner" <ttann...@bloomberg.net> wrote:
On Mar 19, 7:24 pm, "Andrei Iltchenko" <andrei.ilche...@gmail.com>
wrote:
It has been a while since I last posted to this newsgroup, but the
recent article in DDJ by Gigi Sayfan entitled "Practical C++ Error
Handling in Hybrid Environments" (available athttp://www.ddj.com/dept/cpp/197003350)
left me no choice but to react.
What caught my attention is the "cunning" StreamingException class and
some of the author's comments about its design that are plainly
inaccurate. Here's the class
I don't quite know what is "cunning" about the class - at least not in
so far as this is at least the 3rd variant along this line I've seen
recently. I don't particularly like this sort of exception class
either as people tend to inherit from it, and throw exceptions with
large amounts of attached text and no way of programmatically
determining what caused the exception in the first place. I know
exceptions aren't considered to be efficient, but adding this sort of
load onto them is hardly going to help.
The efficiency isn't a problem, really, but the risk of client
code using text to discriminate errors, rather than type, should
certainly be considered. Within a specific application,
however, it might be appropriate.
But the bad thing about this is it is not exception safe in itself,
which is a really really bad thing for an exception class to be.
class StreamingException : public std::runtime_error
{
public:
StreamingException() :
std::runtime_error(""),
ss_(std::auto_ptr<std::stringstream>
(new std::stringstream()))
{
}
That's probably going to be OK, although dodgy if you are running low
on memory. And if it does throw, you are dead. No second chance.
If you run out of memory, either when allocating the
stringstream, or later when streaming into it, you'll get a
bad_alloc exception. Exactly as if you'd run out of memory in
the expression immediately preceding the throw expression. I
don't see any problem here (except maybe that
std::ostringstream() would have been a better choice).
~StreamingException() throw()
{
}
template <typename T>
StreamingException & operator << (const T & t)
{
(*ss_) << t;
return *this;
}
That can throw - slightly unlikely, but certainly more likely than the
constructor.
I'd say more likely than in the constructor, since it is likely
to allocate more memory.
virtual const char * what() const throw()
{
s_ = ss_->str();
return s_.c_str();
}
c_str() can throw.
In theory, yes. In practice, I don't know of an implementation
where it can. (I wonder: since the committee is going to
require contiguity of the data, will they also require that it
not throw?)
The real problem is in the preceding statement: unless the
implementation of std::string uses reference counting (or the
string is small enough to fall under the small string
optimization), the copy *will* allocate memory. Normally, of
course, this function is only called after stack walkback, in
which, probably, enough memory has been freed to allow it to
work. And of course, what() will often be called in conjunction
with other functions which might throw, e.g.:
std::cerr << error.what() ;
(With most implementations I know, if this is the first output
to std::cerr, there will be an allocation of dynamic memory.)
In practice, for most applications, recovery from insufficient
memory isn't possible, and they should abort anyway---I almost
always set the new_handler to abort, for example. (Not that
this suffices. If e.g. I run out of memory when extending the
stack, the new handler doesn't get invoked.)
Still, all things considered, I think I'd use ostrstream (and
yes, I know it's deprecated) here, and avoid the problem.
If it does, because of the throw() spec - bang goes
your program, and you'll have to debug it coz you're unlikely to get
any useful message.
About the same as if you run out of stack in the throw
expression (and probably less likely).
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]