Catching expection from nested function doesn't work - c++

I've got a class cnMeshHelper whose method cnMeshHelper::initialize calls various functions that may throw cnZeroDivisionException.
The stripped down code looks like this:
cnVector cnVector::getNormalized() {
if (getLength() == 0.0) {
#ifdef DEBUG
printf("Throwing exception in cnVector::getNormalized().\n");
#endif // DEBUG
throw cnZeroDivisionException();
}
// ...
}
cnMatrix cnMatrix::getNormalized() {
return cnMatrix(
T.getNormalized(),
B.getNormalized(),
N.getNormalized(),
M.getNormalized() );
}
cnMatrix cnComputeTangentSpace( /* ... */ ) {
cnMatrix mat;
// ...
mat.T = mat.T.getNormalized()
return mat;
}
void cnMeshHelper::initialize(cnMesh& mesh) {
// ...
polygonMatrix = cnComputeTangentSpace( /* ... */ );
}
int main() {
cnMesh* mesh = new cnMesh( /* ... */ );
// ...
try {
cnMeshHelper helper;
helper.initialize(*mesh);
}
catch(cnZeroDivisionException& e) {
cout << "Zero division exceptione caught.\n";
}
}
Now, in some cases, it can happen that the cnMesh* mesh has invalid values that cause to throw an exception in cnVector::getNormalized().
But the problem is, if this is the case, the try-catch clause does not catch the exception. The program just terminates after printing the DEBUG-text in the method above.
Update: Note that I can catch the exception within cnMeshHelper::initialize() but everything "outer" doesn't work.
Even using catch(...) does not work in the main.
Can you tell me why the exception isn't caught ?
Got it !
It happens often, that the issue lies somewhere else. So in this case, too.
The cnMeshHelper destructor throwed a null-pointer because of an uninitialized member. The member was uninitialized because of the cnZeroDivisionException in cnMeshHelper::initialize.
Thanks for you help, anyway.

The part
catch(cnZeroDivisionException& e) {
will catch exactly one kind of exception. But what happens if there is another exception or a non-exception abort (dereferencing NULL, ...)?
So please move the printf into the if sections to see if really an exception of the right type is thrown.
My crystal ball guess is that getLength will reveal something bad since you wrote
...it can happen that the cnMesh* mesh has invalid values...
These invalid values might affect getLength also in some way. (nullpointers, uninitialized memory, other exceptions, ...)

Got it !
It happens often, that the issue lies somewhere else. So in this case, too.
The cnMeshHelper destructor throwed a null-pointer because of an uninitialized member. The member was uninitialized because of the cnZeroDivisionException in cnMeshHelper::initialize.
Thanks for you help, anyway.

Does any of the functions involved have exception specifications (void fn() throw(some_exception))? They will abort the program if an exception that doesn't match the specification is thrown.
I repeat the previous advice of stepping through the code with a debugger.

Related

C++: How to catch exceptions thrown from constructors?

I have a class, call it A, whose constructor takes some input arguments, and may throw an exception if they are incompatible for constructing that object. In my main code, I construct an object of type A as follows:
A my_obj(arg1,arg2,arg3);
and use it. Obviously if the constructor fails and throws the exception, the execution of the program will be terminated after printing out an 'unhandled exception' message.
I, however, would like to give the user more information in this case and tell him/her why the exception has been thrown. So, I need a way to catch the exception.
To this end, one possibility is to enclose the whole code, starting from the declaration of my_obj till the end of the program in a try block and catch the exception afterwards:
try {
A my_obj(arg1, arg2, arg3);
// ...
// about 100 other lines of code being executed if my_obj is created properly
}
catch (std::exception& e) {
// print a user-friendly error message and exit
}
But this looks to me a bit of an 'overkill'. Specifically since no other exceptions are thrown in the remaining 100 lines. Is there any other nicer way to accomplish this?
If the constructor throws, you don't have an object. std::optional<> is a type that means "We might not have an object here".
template <typename T, typename ... Args>
std::optional<T> try_make(Args&& ... args)
{ try {
return make_optional(std::forward(args...));
} catch (...) {
return {};
} }
Then
auto my_obj = try_make<A>(arg1,arg2,arg3);
if (my_obj) {
// about 100 other lines of code being executed if my_obj is created properly
}
One possibility would be the usage of a pointer (better use a smart pointer such as an unique_ptr as in below code). You would leave the unique_ptr empty, call the constructor in the try block and move the pointer into the unique_ptr. After that your other code executes. Surely you have to check for a valid pointer with the operator bool of unique_ptr in a simple if statement.
To simplify the usage of my_obj a reference is taken: A& my_obj_ref = *my_obj;.
std::unique_ptr<A> my_obj;
try {
my_obj = std::move(std::unique_ptr<A>(new A(arg1, arg2, arg3));
}
catch (std::exception& e) {
// print a user-friendly error message and exit
}
if (my_obj) { // needed if your exception handling doesn't break out of the function
A& my_obj_ref = *my_obj;
// ...
// about 100 other lines of code being executed if my_obj is created properly
}
Remember that this way would allocate your object on the heap instead of the stack.
You can abstract the object construction into a function that catches the exception:
template<typename... Args>
A make_a(Args&&... args) {
try {
return A(std::forward(args)...);
}
catch (std::exception& e) {
// print a user-friendly error message and exit
...
std::exit(EXIT_FAILURE);
}
}
// ... in the actual code:
A my_obj = make_a(arg1, arg2, arg3);
The above makes use of the fact that your program is exiting if construction fails. If the requirement were to continue running, the function could return std::optional<A> (or its boost equivalent if you don't have access to C++17.)
You have several options here, depending on how you want control to continue if the construction fails.
If you want to exit the function by throwing an exception, then you don't need to do anything, you can let the A construction exception propagate up.
If you want to exit by either throwing a different exception, or by performing some actions before letting the A construction exception propagate, then use a factory function (perhaps a lambda) that performs those actions, e.g.:
auto a_factory(T x, U y) -> A // or use perfect forwarding
{
try { return A(x, y); }
catch(...) {
log("constructing A failed...");
throw other_exception();
}
}
// ...
A my_obj = a_factory(x, y);
If you want to exit by returning a value, then you could still use the above method, but wrap the calling function in another function that catches expected exceptions and returns a value.
Or you could use the optional (below) or unique_ptr (as covered by other answers) technique, but executing a return statement from the catch block.
If you want to continue execution without a valid A, then you can do:
std::optional<A> opt_my_obj;
try
{
A temp(...args...);
opt_my_obj.swap(temp);
} catch(...)
{
// handling, you could return from the function here
}
// At this point you can test `if ( opt_my_obj )` to branch the flow.
// When you're at a point where you have verified the object exists, you
// can enable normal object syntax by writing:
A& my_obj = *opt_my_obj;
If you have several objects in your function that need this consideration, I would tend to suggest the version of having the whole function wrapped in a try...catch that can handle all the different exceptions.
I tend to do it simple: Throw the human readable message. This strategy works well when there is no choice, and usually, there isn't. There is a catch though, you want exception handling to be reasonably robust, so I package the message inside a std::array<char,4096> truncating if necessary and remembering the zero-terminator (I know that this could blow the stack but it should be fine if we are not in a recursive function), and throw that.
Example:
try
{
Options opts(argv);
SomeResource resource(opts.someParameter());
//...More actions that could throw
}
catch(const std::array<char,4096>& errmessage) //Or rather some other type that contains the message.
{
fprintf(stderr,"Error: %s\n",errmessage.data());
return -1; //Or any non-zero value
}
return 0;
Pros:
Quick to implement new constructors for new classes since there is one exception class only, that will works for everything
You will pick up any system messages right from the source
Cons:
Lack of context: The message will have to say something like "It was not possible to open the file foo: No such file or directory.". Without telling the user what the root cause for the exception. This problem is inherited from the exception model and cannot be solved without treating exceptions as glorified error codes
If you want to branch on exception content, you must parse the message, but I find this rarely needed. Possibly in the context of a compiler, but that would print that message anyway foo:54:1: Error: bar is not a baz.

What will happen is an exception is thrown while executing a throw statement

I have following code snippet:
try
{
if(/*something is true*/)
{
throw Win32Error(msgWin32Error->GetError()); //assume msgWin32Error is NULL
}
}
catch (Win32Error& win32Error)
{
}
Assuming msgWin32Error is NULL in above code snippet, when throw statement gets executed, it will have another exception in turn. What will be the behavior in such circumstance?
Thanks,
Su
There will be no C++ exception here.
You are conflating two things:
C++ exceptions (see: throw, try, catch)
Runtime errors invoked by the operating system (e.g. segmentation fault)
The latter are sometimes also confusingly called "exceptions", but you cannot catch these with C++ catch.
What will happen is that the dereference of msgWin32Error will (probably) cause the Operating System to terminate your application. Control will never even reach your throw instruction.
First of all, when you dereference a NULL pointer, you get undefined behavior. An exception might be thrown (because throwing an exception is in the list of allowable behaviors if UB is invoked), but you can't count on that. However, it's easy to construct a well defined example that gets at what I think you are asking.
char const* foo()
{
throw ExceptionZ();
return "message";
}
void bar()
{
try
{
throw ExceptionX(foo());
}
catch(ExceptionX) { ... }
catch(ExceptionZ) { ... }
}
In this case, the handler for ExceptionZ will be entered. The throw statement in bar does not complete. The exception thrown from foo() propagates before it can.

C++ catching exception in constructor

How can I protect myself from using object which isn't fully created when using exceptions?
Should I catch in constructor ? Or maybe it's bad practice ? If I'll catch in constructor object will be created.
#include <stdio.h>
class A
{
public:
A()
{
try {
throw "Something bad happened...";
}
catch(const char* e) {
printf("Handled exception: %s\n", s);
}
// code continues here so our bad/broken object is created then?
}
~A()
{
printf("A:~A()");
}
void Method()
{ // do something
}
};
void main()
{
A object; // constructor will throw... and catch, code continues after catch so basically we've got
// broken object.
//And the question here:
//
//* is it possible to check if this object exists without catching it from main?
// &object still gives me an address of this broken object so it's created but how can I protect myself
// from using this broken object without writing try/catch and using error codes?
object.Method(); // something really bad. (aborting the program)
};
The language itself has no concept of an object being "invalid" in any detectable way.
If the exception indicates that a valid object can't be created, then it shouldn't be handled within the constructor; either rethrow it, or don't catch it in the first place. Then the program will leave the scope of the object being created, and it won't be possible to incorrectly access it.
If that isn't an option for some reason, then you'll need your own way to mark the object as "invalid"; perhaps set a boolean member variable at the end of the constructor to indicate success. This is flaky and error-prone, so don't do it unless you've got a very good reason.
If the object is in an invalid state when a certain exception is thrown, then I would let the exception unwind the call stack so the caller can be notified (and therefore react) to such things.
However, if the exception is one you can recover from, it may be worth trying to do so depend on your application. Make sure you use something like a logger or even simply stderr to indicate this is happening though.
I am going to suggest a first iteration of doing something more like this:
try {
throw "Something bad happened...";
}
catch(const std::exception e) {
cerr << e.what () << endl ; // Better off in the main
throw ;
}
Two things here:
Unless your exception handler handles the exception, it should throw.
Always use exception classes based upon std::exception to that you can always find out what the problem was as shown above.

C++ try / catch (new to programming and not much info about this clause)

I am new to programming and am having trouble with try / catch clauses.
Here is an example from a textbook that I have:
int main( )
{
char *ptr;
try {
ptr = new char[ 1000000000 ];
}
catch( … ) {
cout << "Too many elements" << endl;
}
return 0;
}
I have tried to look online for a further explanation and the textbook does not exactly tell me what what these clauses actually do or what it is used for.
Any information would be helpful.
EDIT: The textbook I am using is:
C++: Classes and Data Structures by Jeffrey Childs
A try-catch is the C++ construct for exception handling. Google 'C++ exceptions'.
Try catch is a way of handling exceptions:
try
{
// Do work in here
// If any exceptions are generated then the code in here is stopped.
// and a jump is made to the catch block.
// to see if the exception can be handled.
// An exception is generated when somebody uses throw.
// Either you or one of the functions you call.
// In your case new can throw std::bad_alloc
// Which is derived from std::runtime_error which is derived from std::exception
}
// CATCH BLOCK HERE.
The catch block is where you define what exceptions you want to handle.
// CATCH BLOCK
catch(MyException const& e)
{
// Correct a MyException
}
catch(std::exception const& e)
{
// Correct a std::exception
// For example this would cat any exception derived from std::exception
}
You can have as many catch blocks as you like. If you exception matches any of the catch expressions in the catch statement then the associated block of code is executed. If no catch expressions matches an exception then the stack is unwound until it finds a higher level catch block and the processes is repeated (this can cause the application to exit if no matching catch block is found).
Note: If multiple catch expressions match then the lexically first one is used. Only one or none of the catch blocks will be executed. If none then the compiler will look for a higher level try/catch.
There is also a catch anything clause
catch(...)
{
// This is a catch all.
// If the exception is not listed above this will catch any exception.
}
So how does this apply to your code.
int main( )
{
char *ptr;
try
{
// This calls ::new() which can potentially throw std::bad_alloc
// If this happens then it will look for a catch block.
ptr = new char[ 1000000000 ];
// If the ::new() works then nothing happens and you pointer `ptr`
// is valid and code continues to execute.
}
catch( … )
{
// You only have one catch block that catches everything.
// So if there are any statements that generate an exception this will catch
// the excetption and execute this code.
cout << "Too many elements" << endl;
}
// As you have caught all exceptions the code will continue from here.
// Either after the try block finishes successfully or
// After an exception has been handled by the catch block.
return 0;
}
Try-catch blocks are used to trap errors in the code.
At the most basic level, errors occur because the program tries to execute an invalid instruction. That instruction (read: line of code) could be invalid for a number of reasons. In your specific instance, the instruction could be invalid if your program was not able to allocate 1,000,000,000 bytes of memory to story your ptr. The most common exception is trying to access a bad pointer, which is called a Null Pointer Exception, which occurs when you try to perform some action on an Object that either has not been created, or has been deleted (or got corrupt). You will learn to hate that exception.
Using catch(...) tells the program to execute the code inside the catch block if any error occurs inside the code within the try block. There you can handle your error and try to find someway to either fix the error condition or gracefully exit that module.
You can also catch specific errors, which you can find out more about here : http://www.cplusplus.com/doc/tutorial/exceptions/
If you already know C, try/catch achieves the same thing as setjmp/longjmp when used for error handling. Think of try as code for the if condition of setjmp and catch code for else of setjmp. This makes longjmp equivalent to throw in C++, which is used to throw an exception. In your example, probably, the new operator, which calls some memory allocation function internally, throws an exception on seeing a very large number as input by using the C++ throw operator.
void a()
{
.......
longjmp(buf,1); // <--- similar to throw
.......
}
if ( !setjmp(buf) ) // <--- similar to try
{
.......
a();
.......
}
else // <--- similar to catch
{
.......
}
try/catch is a bit more sophisticated than setjmp/longjmp, as for setjmp/longjmp you will need to declare variables which are modified in between setjmp/longjmp calls as volatile, which is not necessary for try/catch.

Way for C++ destructor to skip work when specific exception being thrown?

I have an object on the stack for which I wish its destructor to skip some work when the destructor is being called because the stack is being unwound due to a specific exception being thrown through the scope of the object on the stack.
Now I could add a try catch block inside the scope of the stack item and catch the exception in question and notify the stack object to not run the work to be skipped an then rethrow the exception as follows:
RAII_Class pending;
try {
doSomeWorkThatMayThrowException();
} catch (exceptionToSkipPendingDtor &err) {
pending.notifySkipResourceRelease();
throw;
}
However, I'm hoping there is a more elegant way to do this. For example imagine:
RAII_Class::~RAII_Class {
if (detectExceptionToSkipPendingDtorBeingThrown()) {
return;
}
releaseResource();
}
You can almost do this with std::uncaught_exception(), but not quite.
Herb Sutter explains the "almost" better than I do: http://www.gotw.ca/gotw/047.htm
There are corner cases where std::uncaught_exception() returns true when called from a destructor but the object in question isn't actually being destroyed by the stack unwinding process.
You're probably better off without RAII because it doesn't match your use case. RAII means always clean up; exception or not.
What you want is much simpler: only release resource if an exception is not throw which is a simple sequence of functions.
explicitAllocateResource();
doSomeWorkThatMayThrowException();
explicitReleaseResource(); // skipped if an exception is thrown
// by the previous function.
I would do it the other way around - explicitly tell it to do its work if no exception was thrown:
RAII_Class pending;
doSomeWorkThatMayThrowException();
pending.commit(); // do or prepare actual work
This seems to circumvent the main reason to use RAII. The point of RAII is that if an exception happens in the middle of your code you can still release resources/be destructed properly.
If this isn;t the semantic you want, then don't use RAII.
So instead of:
void myFunction() {
WrapperClass wc(acquireResource());
// code that may throw
}
Just do:
void myFunction() {
Resource r = acquireResource();
// code that may throw
freeResource(r);
}
If the code in the middle throws, the resource won't be freed. This is what you want, rather than keeping RAII (and keeping the name) but not implementing RAII semantics.
Looks like bool std::uncaught_exception(); does the trick if you want to have this behavior for every exception, not just special ones!
You can do without a try-catch:
RAII_Class pending;
doSomeWorkThatMayThrowException(); // intentional: don't release if throw
pending.releaseResource();
Alternatively, you can try a little harder with RAII:
struct RAII_Class {
template<class Op>
void execute(Op op) {
op();
releaseResources();
}
private:
void releaseResources() { /* ... */ }
};
int main(int argc, char* argv[])
{
RAII_Class().execute(doSomeWorkThatMayThrowException);
return 0;
}
Although it would be a kludge at best, if you own the code for the exception class you're interested in, you could add a static data member to that class (bool) that would be set to "true" in the constructor for objects of that class, and false in the destructor (might need to be an int that you increment/decrement instead). Then in the destructor of your RAII class, you can check std::uncaught_exception(), and if true, query the static data member in your exception class. If you get true (or > 0) back, you've got one of those exceptions--otherwise you ignore it.
Not very elegant, but it would probably do the trick (as long as you don't have multiple threads).
I found this website with an interesting discussion about std::uncaught_exception() and an alternative solution to your question that seems much more elegant and correct to me:
http://www.gotw.ca/gotw/047.htm
// Alternative right solution
//
T::Close() {
// ... code that could throw ...
}
T::~T() /* throw() */ {
try {
Close();
} catch( ... ) {
}
}
In this way you're destructor does only one thing and you're protected against throwing an exception during an exception (which I assume is the problem you're trying to solve).