How to catch a base class constructor's exception in C++? - c++

I have a class that is derived from another class. I want to be able to catch and re-throw the exception(s) thrown by the derived class's constructor in my derived class's constructor.
There seems to be a solution for this in C#:
https://stackoverflow.com/a/18795956/13147242
But since there is no such keyword as C#'s baseI have no idea how and if this is possible in C++.
Is there a solution? This would enable me to reuse quite a lot of code.

There is a pretty good example of this here: Exception is caught in a constructor try block, and handled, but still gets rethrown a second time
Ultimately, if you manage to catch an exception in the derived class the only thing you should do is to either rethrow that exception or throw a new one. This is because if the base class constructor does not complete then the derived class will be in an undefined state and you should not use it.

Related

Should private function members be exception safe?

When writing exception-safe code, should all private member functions guarantee at least basic exception safety? What would be best/good practice in this situation? Alternatives?
For example, say I have a class Foo with public function member DoSomething, which calls private function member DoSomeOfIt. DoSomeOfIt may fail due to some functions that I cannot influence, and when it does it may leave the Foo object in a partially modified state which violates Foo's invariants. So I could wrap DoSomeOfIt in a try-catch block and call another private function member UndoThat in the catch block to undo what DoSomeOfIt did. Individually, DoSomeOfIt and UndoThat may not be exception safe, but DoSomething is. Would that be exception safe code? (In this case with strong guarantee)
class Foo {
public:
// I provide strong exception safety guarantee
void DoSomething() {
try {
DoSomeOfIt();
} catch (const std::exception& e) {
UndoThat();
throw;
}
}
private:
// I provide no exception safety guarantee.
DoSomeOfIt() {
// may throw and violate class invariants.
}
// I provide no exception safety guarantee.
UndoThat() {
// undoes everything most recent call of
// DoSomeOfIt did.
}
};
Of course I could simply include the code of DoSomeOfIt and UndoThat in DoSomething, but that could lead to code bloating, and a long function body, whereas breaking up the functions modularizes the tasks and may make the code more readable(?)
DISCLAIMER:
I understand this may be opinion-based. I am not sure if that makes this a bad post, but I'd appreciate any opinions, or experiences where this has lead to issues, or is common practice etc.
This is my opinion.
If there is a possibility that DoSomeOfIt will be used by more than one function, it'll be better to have the exception handling code reside in that function itself -- you don't want to have the exception handling code duplicated across multiple functions. If that is not a possibility, your posted code is fine.
Having said that, if you move the exception handling code to DoSomething, you don't lose anything. In fact, the function becomes better. If it is used in the future by another function, the exception handling is already taken care of. Looked at from that point of view, it will be better to move the exception handling code to DoSomething.

Exception Classes in c++

So I know that an exception class can inherit from the std exception library, but what exactly does an exception class do? It throws exceptions and handles them, but why should I use a class? Can an exception class handle more than 1 type of object?
There is no such thing as an "exception class" in C++; there are
no constraints with regards to the type of what you can throw
and catch. (throw 3.14159; is a perfectly legal C++
statement.) Good programming practice says that except in
special cases, you should throw objects which inherit from
std::exception, but this is not a requirement, and it's not
unusual for programs to throw an int to trigger the end of
program. (Calling exit doesn't invoke all of the destructors,
so the program throws an int, which is caught and returned in
main.)

Is my use of C++ catch clause, families of exception classes, and destruction sane?

Once in a while, I notice some coding pattern that I've had for years and it makes me nervous. I don't have a specific problem, but I also don't remember enough about why I adopted that pattern, and some aspect of it seems to match some anti-pattern. This has recently happened to me WRT how some of my code uses exceptions.
The worrying thing involves cases where I catch an exception "by reference", treating it in a similar way to how I'd treat a parameter to a function. One reason to do this is so I can have an inheritance hierarchy of exception classes, and specify a more general or more precise catch type depending on the application. For example, I might define...
class widget_error {};
class widget_error_all_wibbly : public widget_error {};
class widget_error_all_wobbly : public widget_error {};
void wibbly_widget ()
{
throw widget_error_all_wibbly ();
}
void wobbly_widget ()
{
throw widget_error_all_wobbly ();
}
void call_unknown_widget (void (*p_widget) ())
{
try
{
p_widget ();
}
catch (const widget_error &p_exception)
{
// Catches either widget_error_all_wibbly or
// widget_error_all_wobbly, or a plain widget_error if that
// is ever thrown by anything.
}
}
This is now worrying me because I've noticed that a class instance is constructed (as part of the throw) within a function, but is referenced (via the p_Exception catch-clause "parameter") after that function has exited. This is normally an anti-pattern - a reference or pointer to a local variable or temporary created within a function, but passed out when the function exits, is normally a dangling reference/pointer since the local variable/temporary is destructed and the memory freed when the function exits.
Some quick tests suggest that the throw above is probably OK - the instance constructed in the throw clause isn't destructed when the function exits, but is destructed when the catch-clause that handles it completes - unless the catch block rethrows the exception, in which case the next catch block does this job.
My remaining nervousness is because a test run in one or two compilers is no proof of what the standard says, and since my experience says that what I think is common sense is often different to what the language guarantees.
So - is this pattern of handling exceptions (catching them using a reference type) safe? Or should I be doing something else, such as...
Catching (and explicitly deleting) pointers to heap-allocated instances instead of references to something that looks (when thrown) very like a temporary?
Using a smart pointer class?
Using "pass-by-value" catch clauses, and accepting that I cannot catch any exception class from a hierarchy with one catch clause?
Something I haven't thought of?
This is ok. It's actually good to catch exceptions by constant reference (and bad to catch pointers). Catching by value creates an unnecessary copy. The compiler is smart enough to handle the exception (and its destruction) properly -- just don't try to use the exception reference outside of your catch block ;-)
In fact, what I often do is to inherit my hierarchy from std::runtime_error (which inherits from std::exception). Then I can use .what(), and use even fewer catch blocks while handling more exceptions.
This pattern is definitely safe.
There are special rules that extend the lifetime of a thrown object. Effectively, it exists as long as it is being handled and it is guaranteed to exist until the end of the last catch block that handles it.
One very common idiom, for example, to derive custom exceptions from std::exception, override its what() member function, and catch it by reference so that you can print error messages from a wide variety of exceptions with one catch clause.
No, you're definitely doing it right. See http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.13 , and the rest of the FAQ chapter for that matter.
Yes. So far so good.
Personally I use std::runtime_error as the base of all exception calsses. It handles error messages etc.
Also don't declare more exceptions that you need to. Define an exception only for things that can actually be caught and fixed. Use a more generic exception for things that can not be caught or fixed.
For example: If I develop a library A. Then I will have an AException derived from std::runtime_error. This exception will be used for all generic exceptions from the library. For any specific exceptions where the user of the library can actually catch and do something (fix or mitigate) with the exception then I will create a specific exception derived from AException (but only if there is something that can be done with the exception).
Indeed, Sutter and Alexandrescu recomend this pattern in their 'C++ Coding Standards'.

Avoid slicing of exception types (C++)

I am designing an exception hierarchy in C++ for my library. The "hierarchy" is 4 classes derived from std::runtime_error. I would like to avoid the slicing problem for the exception classes so made the copy constructors protected. But apparently gcc requires to call the copy constructor when throwing instances of them, so complains about the protected copy constructors. Visual C++ 8.0 compiles the same code fine. Are there any portable way to defuse the slicing problem for exception classes? Does the standard say anything about whether an implementation could/should require copy constructor of a class which is to be thrown?
Your exception needs to have a public copy constructor. The compiler has to be able to copy it around for exception handling to work.
The solution to your problem is to always catch by reference instead:
try {
// some code...
throw MyException("lp0 is on fire!");
} catch (MyException const &ex) {
// handle exception
}
(const-ness is optional, but I always put it in because there's rarely a need to modify the exception object.)
Thomas's answer is correct, but I'd also like to suggest you not waste your time by "designing an exception hierarchy". Designing class hierarchies is a notably bad idea, particularly when you could simply derive a couple (and no more than that) of new exception types from the C++ Standard exception classes.
I would steer clear of designing an exception hierarchy distinct to your library. Use the std::exception hierarchy as much as possible and always derive your exceptions from something within that hierarchy. You might want to read the exceptions portion of Marshall Cline's C++ FAQ - read FAQ 17.6, 17.9, 17.10, and 17.12 in particular.
As for "forcing users to catch by reference", I don't know of a good way of doing it. The only way that I have come up with in an hour or so of playing (it is Sunday afternoon) is based on polymorphic throwing:
class foo_exception {
public:
explicit foo_exception(std::string msg_): m_msg(msg_) {}
virtual ~foo_exception() {}
virtual void raise() { throw *this; }
virtual std::string const& msg() const { return m_msg; }
protected:
foo_exception(foo_exception const& other): m_msg(other.m_msg) {}
private:
std::string m_msg;
};
class bar_exception: public foo_exception {
public:
explicit bar_exception(std::string msg_):
foo_exception(msg_), m_error_number(errno) {}
virtual void raise() { throw *this; }
int error_number() const { return m_error_number; }
protected:
bar_exception(bar_exception const& other):
foo_exception(other), m_error_number(other.m_error_number) {}
private:
int m_error_number;
};
The idea is to make the copy constructor protected and force users to call Class(args).raise() instead of throw Class(args). This lets you throw a polymorphicly bound exception that your users can only catch by reference. Any attempt to catch by value should be greeted with a nice compiler warning. Something like:
foo.cpp:59: error: ‘bar_exception::bar_exception(const bar_exception&)’ is protected
foo.cpp:103: error: within this context
Of course this all comes at a price since you can no longer use throw explicitly or you will be greeted with a similar compiler warning:
foo.cpp: In function ‘void h()’:
foo.cpp:31: error: ‘foo_exception::foo_exception(const foo_exception&)’ is protected
foo.cpp:93: error: within this context
foo.cpp:31: error: ‘foo_exception::foo_exception(const foo_exception&)’ is protected
foo.cpp:93: error: within this context
Overall, I would rely on coding standards and documentation stating the you should always catch by reference. Make sure that your library catches exceptions that it handles by reference and throw fresh objects (e.g., throw Class(constructorArgs) or throw;). I would expect other C++ programmers to have the same knowledge - but add a note to any documentation just to be sure.
The two portable ways I have found to stop clients of my library from catching exceptions incorrectly by value are
Throw exceptions from inside virtual raise methods of the exception classes, and make copy constructors protected. (Thanks D.Shawley)
Throw derived exceptions from the library and publish exception base classes for clients to catch. The base classes could have protected copy constructors, which only allows the good way of catching them. (mentioned here for a simmilar question)
The C++ standard does state that copy constructor needs to be accessible at the point of throw. Visual C++ 8.0 in my configuration violated this part of the standard by not enforcing the presence of the copy constructor. In section 15.1.3:
A throw-expression initializes a temporary object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from “array of T” or “function returning T” to “pointer to T” or “pointer to function returning T”, respectively.
If the use of the temporary object can be eliminated without changing the meaning of the program except for the execution of constructors and destructors associated with the use of the temporary object (12.2), then the exception in the handler can be initialized directly with the argument of the throw expression. When the thrown object is a class object, and the copy constructor used to initialize the temporary copy is not accessible, the program is ill-formed (even when the temporary object could otherwise be eliminated)
This answer was posted by OP into the question, I removed it from the question and posted as a separate answer.
I'd say to not use any of the built in C++ exception code. If you must have exceptions, create your own from scratch. That's the only way to be sure they will behave similar let alone be implemented in a similar manner, and to be blunt the implementation of exceptions in C++ is incompetent.

Best practices for defining your own exception classes?

I have some special exception cases that I want to throw and catch, so I want to define my own exception classes.
What are the best practices for that? Should I inherit from std::exception or std::runtime_error?
Yes, it's good practice to inherit from std::runtime_error or the other standard exception classes like std::logic_error, std::invalid_argument and so on, depending on which kind of exception it is.
If all the exceptions inherit some way from std::exception it's easy to catch all common errors by a catch(const std::exception &e) {...}. If you have several independent hierarchies this gets more complicated. Deriving from the specialized exception classes makes these exceptions carry more information, but how useful this really is depends on how you do your exception handling.
I'm not a C++ developer, but one thing we did in our C# code was create a base class exception for our framework, and then log the exception thrown in the constructor:
public FrameworkException(string message, Exception innerException)
: base(message, innerException)
{
log.Error(message, innerException);
}
...
Any derived exception just has to invoke it's base constructor and we get consistent exception logging throughout. Not a big deal, but useful.
It is a good when exception is placed in some scope. For instance class Manipulation can declare inside exception classes Error.
and catch them like
catch ( const Manipulation::InputError& error )
catch ( const Manipulation::CalculationError& error )
In such cases they can be just empty classes without any additional error information unless you design allows those exceptions fly much upper where you catch all standard exceptions.
In my opinion it doesn't matter if you inherit from std::exception or not. For me the most important thing about defining exceptions are:
Having the exception class names be useful and clear.
Clearly documenting (writing comments) when exception will get thrown by a function or class method. This is the single biggest failure point in exception handling in my opinion.
It doesn't make a big difference, since std::runtime_error also inherits from std::exception. You could argue that runtime error conveys more information about the exception, but in practice, people often just derive from the base exception class.