A question related to deriving standard exception classes - c++

/* user-defined exception class derived from a standard class for exceptions*/
class MyProblem : public std::exception {
public:
...
MyProblem(...) { //special constructor
}
virtual const char* what() const throw() {
//what() function
...
}
};
...
void f() {
...
//create an exception object and throw it
throw MyProblem(...);
...
}
My question is why there is a "const throw()" after what()?
Normally,if there is a throw() , it implies that the function before throw()
can throw exception.However ,why there is a throw here?

Empty braces in "throw()" means the function does not throw.

The const is a separate issue to throw().
This indicates that this is a const method. Thus a call to this method will not change the state of the object.
The throw() means the method will not throw any exceptions.
To the USER of this method, the method will only return through normal means and you do not need to worry about the call generating exceptions.
To the IMPLEMENTER of the method there is more to worry about.
Unlike Java this is not a compile time constraint but a runtime constraint. If the implementer writes the function so that it accidentally throws an exception out of the method then the runtime will stop the application dead (no unwinding of the stack no destructors etc).
But the convention is that the implementer will take the extra precautions to catch all internal exceptions.
PS
You may want to derive from std::runtime_error
(From Comment#onebyone.livejournal.com): Not quite.
The no throw specifier is actively used. It is an indication of exception safety demonstrates that the method provides the no throw guarantee
On the other hand the other exception specifiers are not used because they are too dangerous. If you get them wrong it causes an application termination via (std::unexpected). The default action is application termination without unwinding the stack and without cleaning up using object destructors. In MHOP this is hardly ever desirable.

The const qualifies the function what(), saying it does not modify the internal structure of the exception object.
The throw() means it doesn't throw an exception, either - as noted by OneByOne and Checkers.
The two words are largely unrelated, even though they appear right next to each other in the signature.

Related

Copy std::exception object to a struct member in C++ [duplicate]

I have an API which internally has some exceptions for error reporting. The basic structure is that it has a root exception object which inherits from std::exception, then it will throw some subclass of that.
Since catching an exception thrown in one library or thread and catching it in another can lead to undefined behavior (at least Qt complains about it and disallows it in many contexts). I would like to wrap the library calls in functions which will return a status code, and if an exception occurred, a copy of the exception object.
What is the best way to store an exception (with it's polymorphic behavior) for later use? I believe that the c++0x future API makes use of something like this. So what is the best approach?
The best I can think of is to have a clone() method in each exception class which will return a pointer to an exception of the same type. But that's not very generic and doesn't deal with standard exceptions at all.
Any thoughts?
EDIT: It seems that c++0x will have a mechanism for this. It is described as "library magic". Does that mean that is doesn't require any of the language features of c++0x? if not, are there any implementations which are compatible with c++03?
EDIT: Looks like boost has an implementation of exception copying. I'll keep the question open for any non boost::copy_exception answers.
EDIT: To address j_random_hacker's concerns about the root cause of the exception being an out of memory error. For this particular library and set of exceptions, this is not the case. All exceptions derived from the root exception object represent different types of parsing errors caused by invalid user input. Memory related exceptions will simply cause a std::bad_alloc to be thrown which is addressed separately.
As of C++11, this can be done using std::exception_ptr.
(I use this in a class that makes an std::thread interruptible provided that the underlying thread implementation is a POSIX thread. To handle exceptions that may be thrown in the user's code - which causes problems if they are thrown in a certain critical section of my implementation - I store the exception using std::exception_ptr, then throw it later once the critical section has completed.)
To store the exception, you catch it and store it in the ptr variable.
std::exception_ptr eptr;
try {
... do whatever ...
} catch (...) {
eptr = std::current_exception();
}
You can then pass eptr around wherever you like, even into other threads (according to the docs - I haven't tried that myself). When it is time to use (i.e. throw) it again, you would do the following:
if (eptr) {
std::rethrow_exception(eptr);
}
If you want to examine the exception, you would simply catch it.
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch (const std::exception& e) {
... examine e ...
} catch (...) {
... handle any non-standard exceptions ...
}
You have what would be what I think is your best, only answer. You can't keep a reference to the original exception because it's going to leave scope. You simply have to make a copy of it and the only generic way to do that is with a prototype function like clone().
Sorry.
You're allowed to throw anything, including pointers. You could always do something like this:
throw new MyException(args);
And then in the exception handler store the caught pointer, which will be fully polymorphic (below assuming that MyException derives from std::exception):
try {
doSomething(); // Might throw MyException*
} catch (std::exception* pEx) {
// store pEx pointer
}
You just have to be careful about memory leaks when you do it this way, which is why throw-by-value and catch-by-reference is normally used.
More about catch-by-pointer: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.8
The reason why catching an exception thrown in one library and catching it in another can lead to undefined behavior is that these libraries could be linked with different Runtime libraries. If you will return exception from a function instead of throwing it you will not avoid that problem.
My utility library has an AnyException class that is basically the same as boost::any without the casting support. Instead, it has a Throw() member that throws the original object stored.
struct AnyException {
template<typename E>
AnyException(const E& e)
: instance(new Exception<E>(e))
{ }
void Throw() const {
instance->Throw();
}
private:
struct ExceptionBase {
virtual void Throw() const =0;
virtual ~ExceptionBase() { }
};
template<typename E>
struct Exception : ExceptionBase {
Exception(const E& e)
: instance(e)
{ }
void Throw() const {
throw std::move(instance);
}
private:
E instance;
};
ExceptionBase* instance;
};
This is a simplification, but that's the basic framework. My actual code disables copying, and has move semantics instead. If needed, you can add a virtual Clone method to the ExceptionBase easily enough... since Exception knows the original type of the object, it can forward the request onto the actual copy constructor, and you immediately have support for all copiable types, not just ones with their own Clone method.
When this was designed, it was not meant for storing caught exceptions... once an exception was thrown, it propagated as normal, so out-of-memory conditions were not considered. However, I imagine you could add an instance of std::bad_alloc to the object, and store it directly in those situations.
struct AnyException {
template<typename E>
AnyException(const E& e) {
try {
instance.excep = new Exception<E>(e);
has_exception = true;
} catch(std::bad_alloc& bad) {
instance.bad_alloc = bad;
bas_exception = false;
}
}
//for the case where we are given a bad_alloc to begin with... no point in even trying
AnyException(const std::bad_alloc& bad) {
instance.bad_alloc = bad;
has_exception = false;
}
void Throw() const {
if(has_exception)
instance.excep->Throw();
throw instance.bad_alloc;
}
private:
union {
ExceptionBase* excep;
std::bad_alloc bad_alloc;
} instance;
bool has_exception;
};
I haven't actually tested that second bit at all... I might be missing something glaringly obvious that will prevent it from working.

Why smart pointer templates need to disable exception throwing in constructor

I find such question while reading the Smart Pointer Template Classes in C++ primer plus.
The book gives an example of how auto_ptr class is implemented, like this,
template<class X> class auto_ptr {
public:
explicit auto_ptr(X* p = 0) throw();
...};
throw() at the end of constructor means this constructor doesn't throw an exception.
I know this is deprecated, but I do not know why it needs to disable its exception throwing.
throw() doesn't disable exception throwing. It simply says that the function does not throw any exceptions. That's a statement about the code in the constructor: there's nothing there that will throw an exception that escapes from the constructor. That means that either the code in the constructor doesn't throw any exceptions (for example, int i = 3; will not throw an exception), or that anything that does throw an exception is enclosed in a try block whose catch clauses don't throw anything.
Because if the constructor of auto_ptr would throw exceptions, the pointer might be lost and then cause memory leak. For example:
auto_ptr<int> ap(new int);
The memory allocated couldn't be deallocated again if the constructor failed.
They are declaring an intent/promise not to throw exceptions - they still can, but will be smacked down hard by the runtime if they do.
The reason to use noexcept over throw() is mostly academic.

Why does std::runtime_error::what() return const char* instead of std::string const&

Why does std::runtime_error::what() return const char* instead of std::string const& ?
In many cases a direct return of a reference to the embedded string would be handy and it could avoid some overhead. So what is the rationale for not returning e.g. a const reference to the internal string in the first place and not offering an overloaded function ? I guess it goes along with a string ctor being able to throw an exception as well but I do not see the risk of returning a string reference.
std::runtime_error inherits from std::exception which defines virtual const char* what() const throw(); so the simplest response is that it's an overload of the function and that you can be sure that any standard exception defines it in such way. It may (depending on the implementation) be possible to return the std::string, but it would be inconsistent with the rest of standard library.
I think the reason why the what() returns const char* is that you can avoid any operation that can possibly fail (especially that can throw exception). Consider the following code, which shouldn't fail
virtual const char* what() const throw() {
return "An error has occured";
}
However in the following code the allocation of std::string may fail, throwing an exception:
std::string what() const throw() {
return std::string("An error has occured");
}
If the string's constructor threw here, the application would most likely crash no matter what, because the function specifies throw().
Using std::string inside an exception introduce the need to allocate memory which may not be possible (note that std::bad_alloc inherits from std::exception too).
There is not necessarily an embedded std::string. The what member function is virtual, i.e. it's designed to be overridden. The chief reason for overriding it is to provide the string in some other way than via the mechanism used by std::runtime_error (whatever that mechanism is, most probably a stored std::string).
While runtime_error does take a std::string as a parameter, so it could hold on to it and return it as you suggest, the what() method is inherited from std::exception, so is more general.
The overhead of throwing an exception is likely to be high already, with stack unwinding, so you should not be worrying about this little extra bit of overhead.

std exceptions inviting unsafe usage?

It is recommended that you always throw something derived from std::exception and there are a few predefines specialisations such as std::runtime_error
std::exception's interface is given in terms of non-throwing accessors. Great. Now look at the constructor for std::runtime_error
class runtime_error : public exception {
public:
explicit runtime_error (const string &);
};
So if I do this
try {
foo ();
}
catch (...) {
throw std :: runtime_error ("bang");
}
it's entirely possible that foo threw because it's out of memory, in which case constructing the string argument to runtime_error can also throw. This would be a throw-expression which itself also throws: won't this will call std::terminate?
Doesn't this mean we should always do this instead:
namespace {
const std :: string BANG ("bang");
}
...
try {
foo ();
}
catch (...) {
throw std :: runtime_error (BANG);
}
BUT WAIT this won't work either, will it? Because runtime_error is going to copy its argument, which may also throw...
...so doesn't this mean that there is no safe way to use the standard specialisations of std::exception, and that you should always roll your own string class whose constructor only fails without throwing?
Or is there some trick I'm missing?
I think your main problem is that you are doing catch(...) and translating to a std::runtime_error thereby losing all type information from the original exception. You should just rethrow with throw().
Practically, if you are short of memory you are likely have a bad_alloc exception thrown at some point and there's not a lot else you can - or should - do. If you want to throw an exception for a reason other than an allocation failed then you are not likely to have a problem constructing a sensible exception object with meaningful contextual information. If you hit a memory issue while formatting your exception object there's not a lot you can do other than propagate the memory error.
You are right that there is a potential problem if you construct a new string object to construct an exception, but if you want to format a message with context this can't be avoided in general. Note that the standard exception objects all have a const char* constructor (as of last week) so if you have a const char* that you want to use you don't have to construct a new std::string object.
std::runtime_error must copy it's argument, but not necessarily as a new string object. There could be an area of statically allocated memory which it can the contents of its argument to. It only has to fulfil the what() requirements which only requires returning a const char *, it doesn't have to store a std::string object.
This would be a throw-expression which itself also throws: won't this
will call std::terminate?
No, it wouldn't. It would just throw the exception about insufficient memory. The control will not reach the outer throw part.
BUT WAIT this won't work either, will it? Because runtime_error is
going to copy its argument, which may also throw...
Exception classes with a throwing copy-constructors are as evil as throwing destructors. Nothing that can really be done about it.
std::runtime_error is designed to treat the usual runtime errors, not
out of memory or other such critical exceptions. The base class
std::exception does not do anything which may throw; nor does
std::bad_alloc. And obviously, remapping std::bad_alloc into an
exception which requires dynamic allocation to work is a bad idea.
The first thing is what would you want to do if you happen to have a bad_alloc exception because you're out of memory?
I'd say in a classic C++ program, you'd want to have the program somehow trying to tell you what happened and then terminates.
In a classic C++ program you'd then let the bad_alloc exception propagate to the main section of the program. The main will contain an arragement of try/catch like this:
int main()
{
try
{
// your program starts
}
catch( const std::exception & e )
{
std::cerr << "huho something happened" << e.what() << std::endl;
}
catch( ... )
{
std::cerr << "huho..err..what?" << std::endl;
}
}
you'll only use catch( ... ) inside the main and at the starting functions of threads. Contrary to some other languages like Java you're not expected to catch all possible exceptions locally. You just let them propagate until you catch them where you wanted to.
Now if you have code that specifically must check std::bad_alloc, you should only catch( const std::bad_alloc & ) locally. And there it should maybe wise to do something else rather than just rethrow another exception.
I found in The C++ Programming Language ยง14.10 also that the C++ exception-handling mechanism keeps a bit of memory to itself for holding exceptions, so that throwing a standard library exception will not throw an exception by itself. Of course it is possible also to let the exception-handling mechanism run out of memory if you really code something perverted.
So, to sum up, if you do nothing and let big exceptions like bad_alloc propagate nicely where you want to catch them, in my opinion you're safe. And you should not use catch( ... ) or catch(const std::exception & ) anywhere except in the main function and in the starting functions of threads.
Catching all exceptions to rethrow a single exception is really the last thing to do. You lose every advantages you got with the C++ exception-handling mechanism.

What is the point of `void func() throw(type)`?

I know this is a valid c++ program.
What is the point of the throw in the function declarement? AFAIK it does nothing and isnt used for anything.
#include <exception>
void func() throw(std::exception) { }
int main() { return 0; }
It specifies that any std::exception can be thrown from func(), and nothing else. If something else is thrown, it will call an unexpected() function which by default calls terminate().
What this means is that throwing something else will almost certainly terminate the program, in the same manner as an uncaught exception, but the implementation will have to enforce this. This is normally much the same as putting a try{...}catch(){...} block around func(), which can inhibit performance.
Usually, exception specifications aren't worth it, according to the Guru of the Week column about it. The Boost guidelines say that there might be a slight benefit with a blank throws() for a non-inline function, and there are disadvantages.
That is an exception specification, and it is almost certainly a bad idea.
It states that func may throw a std::exception, and any other exception that func emits will result in a call to unexpected().
This is a C++ exception specification. It declares that the particular function will potentially throw a std::exception type.
In general though exception specifications in C++ are considered a feature to avoid. It's an odd feature in that it's behavior is declared at compile time but only checked at runtime (very different from say Java's version).
Here is a good article which breaks down the feature
http://www.gotw.ca/publications/mill22.htm
This is an exception specification. It says that the only exception that func() can throw is std::exception (or a derivative thereof). Attempting to throw any other exception will give std::unexpected instead.
Exception specification. The type(s) following the throw keyword specifies exactly what all, if any, exceptions the function can throw. See 15.4 of the draft.
Note: A function with no exception-specification allows all exceptions. A function with an empty exception-specification, throw(), does not allow any exceptions.
Basically this:
void func() throw(std::exception,B) { /* Do Stuff */}
Is just shorthand fro this:
void func()
{
try
{
/* Do Stuff */
}
catch(std::exception const& e)
{
throw;
}
catch(B const& e)
{
throw;
}
catch(...)
{
unexpected(); // This calls terminate
// i.e. It never returns.
}
}
Calling terminate() is rarely what you want, as the stack is not unwound and thus all your efforts in RAII is wasted. The only exception to the rule is declaring an empty throw list and this is mainly for documentation purposes to show that you are supporting the no-throw exception gurantee (you should still manually catch all exceptions in this situation).
Some important (imho) places that should be no-throw are destructors and swap() methods. Destructors are rarely explicitly marked no-throw but swap() are quite often marked no-throw.
void myNoThrowFunc() throws() // No-Throw (Mainlly for doc purposes).
{
try
{
/* Do Stuff */
}
catch(...) // Make sure it does not throw.
{
/* Log and/or do cleanup */
}
}