Exceptions: Bad Design?

M

Matt Bitten

Thinking about the standard exception classes. They all have
constructors that take a (char *). Say I do this:

std::string s("Got me a errer. Durn.");
throw std::exception(s.c_str());

s, along with its c_str() value, is going to vanish when it goes out of
scope. That means that the constructor for std::exception had better
copy the string. And that means it has to do an allocation. And THAT
means it might throw.

And, if you ask me, the fact that a constructor for an exception object
might throw, sounds like a Very Bad Idea (tm).

Or am I missing something?
 
G

GB

Matt said:
Thinking about the standard exception classes. They all have
constructors that take a (char *). Say I do this:

std::string s("Got me a errer. Durn.");
throw std::exception(s.c_str());

s, along with its c_str() value, is going to vanish when it goes out of
scope. That means that the constructor for std::exception had better
copy the string. And that means it has to do an allocation. And THAT
means it might throw.

And, if you ask me, the fact that a constructor for an exception object
might throw, sounds like a Very Bad Idea (tm).

Or am I missing something?

The constructor of std::exception does not take a string argument.
Neither does std::bad_alloc.

Gregg
 
A

Alf P. Steinbach

* Matt Bitten:
Thinking about the standard exception classes. They all have
constructors that take a (char *). Say I do this:

std::string s("Got me a errer. Durn.");
throw std::exception(s.c_str());

s, along with its c_str() value, is going to vanish when it goes out of
scope. That means that the constructor for std::exception had better
copy the string. And that means it has to do an allocation. And THAT
means it might throw.

And, if you ask me, the fact that a constructor for an exception object
might throw, sounds like a Very Bad Idea (tm).

Or am I missing something?

Yes, that no exception class design or error handling strategy can fix that
situation in the sense of providing guarantees.

When you're out of memory you're taking chances even with a deallocation
call, even just evaluating 2+2 (which might push some values on the stack,
and with modern OS that area so far allocated for stack might be full).

It's all about probability and Quality of Implementation. On the bright
side, in C++ it's unusual to have several KiBs allocated for an exception
object, and in C++ a quality implementation will not allocate dynamically
unless really needed (small buffer optimization). Dynamic allocation of many
KiBs per exception object is not unusual in Java...
 
M

Matt Bitten

--- GB said:
The constructor of std::exception does not take a string argument.
Neither does std::bad_alloc.

Yes, you're right. I wasn't thinking. But change "std::exception"
to "std::range_error" in my code, and the question still applies.

std::string s("Got me a RAYNJ errer. Dubul Durn.");
throw std::range_error(s.c_str());
 
G

Gregg

Yes, you're right. I wasn't thinking. But change "std::exception"
to "std::range_error" in my code, and the question still applies.

std::string s("Got me a RAYNJ errer. Dubul Durn.");
throw std::range_error(s.c_str());

The original scenario you posted would have been more serious though,
because it would have meant that the exception object thrown when an
allocation error occurs (std::bad_alloc) would itself have to allocate a
string.

In fact, I think the issue you are raising is the very reason the
std::exception constructor does not take a string argument even though it
has a what() member.

Gregg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,201
Messages
2,571,049
Members
47,655
Latest member
eizareri

Latest Threads

Top