Related
Is it possible to make a destructor catch exceptions and then re-throw them?
If so, how would I do that, since there isn't a clear place for a try statement?
Basically, I want to ideally do:
CMyObject::~CMyObject()
{
catch(...) // Catch without a try. Possible?
{
LogSomeInfo();
throw; // re-throw the same exception
}
// Normal Destructor operations
}
Background
I have a large, complex application that is throwing an unhandled exception somewhere.
I don't have easy access to main or the top level message-pump or anything similar, so there's no easy place to catch all unhandled exceptions.
I figure any unhandled exception has to pass through a bunch of destructors as the stack is unwound. So, I'm contemplating scattering a bunch of catch statements in destructors. Then at least I'd know what objects are in play when the exception is thrown. But I have no idea if this is possible, or advisable.
EDIT: You can use std::uncaught_exception to check if an exception is currently being thrown (i.e. if stack unwinding is in progress due to an exception). It is not possible to catch that exception or otherwise get access to it from your destructor. So if your logging doesn't need access to the exception itself, you can use
CMyObject::~CMyObject()
{
if(std::uncaught_exception()) {
LogSomeInfo(); // No access to exception.
}
// Normal Destructor operations
}
Note that this question was asked in 2013, meanwhile std::uncaught_exception was replaced with std::uncaught_exceptions (notice the additional s at the end) which returns an int. For a rationale, see http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4152.pdf, so if you are using C++17, you should prefer the new version. The above paper also explains why the old std::uncaught_exception will not work as expected in some situations.
Another option might be std::set_terminate. This is useful if you want to have a method called when an exception is not caught and about to terminate the program. In the terminate handler, I usually print some information about the exception and a (demangled) backtrace of where it originates from to my log file before finally terminating the program. This is compiler and system specific, but a real helper as it saves a lot of time if you write server processes and often the log file is all you get from ops.
You can use std::uncaught_exception() which returns true if and only if there is an exception being processed. It has been available since C++98, and is superseded by std::current_exception which returns a std::exception_ptr.
However you must be careful not to throw another exception in an unguarded context, otherwise std::terminate will be caught. Example:
X::~X() {
if (std::uncaught_exception()) {
try {
LogSomeInfo();
// and do something else...
} catch(...) {}
}
}
A destructor cannot catch the exception that is causing the destruction of the instance.
You can only know if there is any "active exception" (see uncaught_exception) during the destruction (or, in C++17, how many of them there are there with uncaught_exceptions) but it's possible that the exception(s) are indeed going to be handled after that.
Dealing with exceptions is very hard, much harder than someone may think at a first sight and the reason is that exception safety doesn't scale by composition. This in my opinion means that is basically impossible to have non trivial stateful subsystems with strong exception safety (in case of an exception being thrown nothing happened to the internal state). This was discovered long ago (see 1994 Tom Cargill's "Exception handling: A False Sense of Security") but apparently is still ignored by large part of the C++ community.
The only reasonable way to handle exceptions I can think to is to have subsystems with clear well defined interfaces with thick "walls" (no side effect happening inside may escape), and that can be re-initialized to a well known state from scratch if needed when something goes wrong. This not trivial but can be done correctly to a reasonable extent.
In all other cases the global state of the system when an exception is caught is indefinite at best at the point of catch and there are in my opinion few use cases in which you can do anything in such a condition except dying immediately as loudly as possible instead of taking further actions without indeed knowing what is going on (dead programs tell no lie). Even keeping on calling destructors is somewhat questionable in my opinion.
Or you may try to be as functional as possible, but that's not an easy path either (at least for my brain) and it's also moving far away from reality (most computers are mutable objects with many billions of bits of mutable state: you can pretend this is not the case and they're instead mathematical functions with no state and with predictable output dependent on input... but in my opinion you're just deluding yourself).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
Several resources are describing the topic "Exception Handling" like Wikipedia and vast more number of resources. But very few of them explained that what is the Exception itself. Maybe they assumed that its very obvious. I could find a good short explanation on Oracle documentation:
Definition: An exception is an event, which occurs during the execution of a
program, that disrupts the normal flow of the program's instructions.
The rest of this paper is about exception on Java programming. But I do not understand Java well to read the entire of documentation. I need a clarify on exception.
edit:
I need an example of Exception. For example in C++.
And I need to know what is its difference by bug?
Conceptually, an exception is a scenario that shouldn't happen in a normal run of your program. For example, a remote server being unavailable, an input being in an incorrect format, a file not being found, the system running out of memory... Depending on the kind and the circumstances, it may or may not be possible for the program to handle it.
Technically, an exception is represented as a simple object. Exception objects are kind of special in the sense that they can be "thrown" from an inner level of execution to an outer level that "catches" them, typically abandoning the code in all levels between the thrower and the catcher.
C++, Java and C# are a few examples of many languages that have a form of exception handling mechanism. Strictly speaking, C does not have the concept of exceptions (out-of-the-box, at least).
"Throwing an exception" (sometimes also called "raising an exception") is a way to end a function when, for some reason, the function cannot complete the task it is expected to complete.
Example: You have a function f that takes a float argument and is expected to compute and return its natural logarithm. Now at some point during the calculations it turns out that the argument that it was passed is 0. There is no way to compute the logarithm of 0, so what should the function do?
One way to handle this situation is to return a special value (such as NaN, the not-a-number value of float), but this can be misleading to the caller of the function: The function was called on some variable, and returned some value. All looks normal, while in reality nothing is normal – the function could not do its job.
Therefore, another way of handling this is to throw an exception. The effect is that the function ends, but does not return any value. Now, obviously, the calling function has a problem, because the normal flow of things has been disturbed: No value was returned from the function call. There are two possibilities for what can happen next: Either the calling function was prepared for this by having put the call of f in a try-catch clause:
try {
log_of_val = f(val);
} catch (const exception &e) {
/* Description of what to do when
an exception is thrown by f. */
}
If the exception that is thrown by f matches the type of exception defined in one of the catch-clauses, then the first such catch-clause is executed.
If there is no such catch-clause, the exception is thrown again, i.e. the calling function also ends abruptly and the caller of the caller is stopped to check whether there is some catch-code for the exception. If not, it also ends and that functions calling function is stopped, and so on, until the top of the call stack is reached (i.e. the level of main) and if there is still no catch-clause there, the entire program is terminated and the operating system is informed of the abortion of the process.
So an exception has the power to bring down the entire process if there is no appropriate catch-clause. But an exception is far better than simply calling something like exit(1), because it does not immediately terminate the process. It first gives the caller a chance to react to the problem, and then the caller's caller, and so on.
The exception throwing mechanism also ensures that local variables are properly destructed and de-allocated before the current function ends. So, as far as automatic variables and dynamic memory that is managed by smart pointers and the like is concerned, you won't get memory leaks and similar problems.
To sum up, exceptions (and the whole throwing and catching mechanism) is a way to deal with unusual, but possible and to some extent expected events in the flow of a program. Typically, it's events that can occur in a function call that render the proper execution of the function impossible, but that cannot be prevented from within the function. These events are often the responsibility of the calling function if it passes unsuitable arguments, or of the user who gives unsuitable input to the program. Also problems related to the state of the system, such as insufficient memory, tend to be handled by throwing exceptions.
But unlike bugs, the programmer who wrote a function anticipated the possiblility of the problem and prepared the code with suitable throw and catch code to deal with it by having the program shut down in a controlled way, or otherwise react to the problem appropriately.
Regarding the core of your question: What is the exception itself? The exception is an object created at the time when the "exception is thrown". You could view it as some kind of replacement for the return value, because the exception object is in fact passed to the caller, in a similar way as the return value would. But unlike with an actual return value, the caller is informed that what has happened is an exception and that it must handle this in the way I've described above. Further more, the data type of the exception is not the data type declared as return type of the function. In fact, it can be (almost) any data type. In particular, it can be a complex object with member variables that are initialized with values that describe the circumstances of the exception. A typical exception object is C++ is of class type, often (but not necessarily) defined as something like this:
#include <exception>
class my_exception : public std::exception
{
public:
explicit my_exception(const char *description)
: std::exception() , description_(description)
{ }
virtual const char *what() const noexcept
{ return description_; }
private:
const char *description_;
};
So it's a user-defined object that is constructed on a string, stores a pointer to the string internally, and provides a member function what() that returns the string. The idea is that the string is defined when the exception is thrown, and that it contains some description of the problem.
The caller of f can then catch this type of exception by enclosing the call to f in a try-clause and adding a catch-clause for my_exception:
try
{
f();
} catch (const my_exception &e) {
std::cerr << "A problem has occurred when evaluating f(): "
<< e.what()
<< std::endl;
}
In this example, we use the exception object's what() function to print a description of the problem. After the catch-clause is completed, the caller will continue as normal. (If this is not desired, throw; can be used inside the catch-clause to re-throw the exception so it is passed to the caller's caller, and so on.)
Note, again, that exception can be user-defined objects, and they can be derived from std::exception, and they can override the what() function to return a problem description as a string, but none of this is necessary. You can also throw the string itself, or an int as exception.
Exception is an object which you throw during executing something IF anything goes wrongs.
Like that when you are "try"ing to execute the method, you can "catch" anything that ges wrong without crashing your program.
void doSmth()
{
.
.
.
if(somthingWentWorng)
throw Exception("Not Good!")
.
.
.
}
Then whenever you want to call doSmth()
try
{
doSmth();
}
catch (Exception &e)
{
cout << e.what() << endl;
}
this way, if somthing went wrong while executing doSmth you can figure it out without you application being crashed.
Consider the following horribleness:
#include <iostream>
struct thing
{
thing()
{
std::cout << "thing ctor\n";
throw 5;
}
};
void SomeTerminateHandler()
{
std::cout << "Uncaught exception!?\n";
}
int IHopeThisGetsCalledFirst()
{
std::cout << "IHopeThisGetsCalledFirst()\n";
std::set_terminate(SomeTerminateHandler);
return 2;
}
const int x = IHopeThisGetsCalledFirst();
const thing y;
int main()
{
}
Output:
IHopeThisGetsCalledFirst()
thing ctor
Uncaught exception!?
This relies on static initialization order (which I can mess with, for MSVS anyway) so it's not ideal even if the following questions have acceptable answers.
What can I do in SomeTerminateHandler to 'catch' the exception so I can display an error dialog box or log out the details of the error?
abort is called after SomeTerminateHandler in the above program. Why? This says "The terminate handler by default calls cstdlib's abort function." - but I'm not using the default terminate handler, and mine doesn't call abort.
Is there anything I can do to handle exceptions in static initialization time. If not, why not? Why isn't there something in the language to allow this?
What can I do in SomeTerminateHandler to 'catch' the exception so I can display an error dialog box or log out the details of the error?
Nothing - only exception handlers can access the thrown exception.
abort is called after SomeTerminateHandler in the above program. Why?
Your terminate handler must not return; the standard (C++11, 18.8.3.1) requires that it "shall terminate execution of the program without returning to the caller" - the page you link to also says the same thing. If you break that requirement, then anything could happen.
Is there anything I can do to handle exceptions in static initialization time?
You can catch the exception in the constructor; or you can avoid complex static objects.
If not, why not? Why isn't there something in the language to allow this?
I can't answer why, but C++ doesn't handle complex static objects at all well. Even if your compiler does have non-standard extensions to specify the initialisation order, I suggest avoiding them if at all possible.
Is there anything I can do to handle exceptions in static
initialization time. If not, why not? Why isn't there something in the
language to allow this?
C++ doesn't have any well-defined constructs for user-defined objects externally linked or created at file scope. It's generally problematic with issues like undefined initialization order. Without a clear definition of what should happen with respect to things like initialization order, it would be difficult to define meaningful try/catch behavior (where would one put the try/catch block, e.g., if any object constructed in any compilation unit in a system can throw?).
For a more philosophical answer, I'd venture to guess that one of the problems C++ aims to address is the need for a lot of global objects. The language doesn't bother to provide well-defined behavior for them as they should generally be avoided in the first place.
If you want a quick fix, we can construct things in a lazy fashion:
thing& my_thing()
{
static thing obj;
return obj;
}
This ensures that thing won't be constructed until this function is first called which means it will not be constructed outside of your main entry point unless you have another global object which is calling this (directly or indirectly) through its constructor.
Ultimately it would be better if you avoid global instances of user-defined types this way all together, but if you can't resist the temptation, I recommend at least applying a form of lazy initialization liberally.
Is there anything I can do to handle exceptions in static initialization time. If not, why not?
No, because the initialization order is not specified by the standard.
The only thing is not to do it, or at least minimize number of objects that are initialized before main. It would be also very good to put them all in one place.
abort is called after SomeTerminateHandler in the above program. Why? This says "The terminate handler by default calls cstdlib's abort function." - but I'm not using the default terminate handler, and mine doesn't call abort.
Your handler is most likely not initialized on time (the exception is thrown before your handler is initialized).
I have a pretty large application that dynamically loads shared objects and executes code in the shared object. As a precaution, I put a try/catch around almost everything in main. I created a catch for 3 things: myException (an in house exception), std::exception, and ... (catch all exceptions).
As part of the shared objects execution, many pthreads are created. When a thread throws an exception, it is not caught by main. Is this the standard behavior? How can I catch all exceptions, no matter what thread they are thrown from?
Will main() catch exceptions thrown from threads?
No
When a thread throws an exception, it is not caught by main. Is this the standard behavior?
Yes, this is standard behaviour.
To catch an exception originating in thread X, you have to have the try-catch clause in thread X (for example, around everything in the thread function, similarly to what you already do in main).
For a related question, see How can I propagate exceptions between threads?
Your question is asking for something that isn't conceptually possible.
Try blocks are defined as dynamic constructs of the stack. A try block catches exceptions thrown by code reached dynamically, by call, from its contents.
When you create a new thread, you create a brand-new stack, that is not at all part of the dynamic context of the try block, even if the call to pthread_create is inside the try.
No, main will not catch exceptions thrown from other threads. You would need to use a non-standard, platform specific facility that addresses unhandled exceptions in order to aggregate the handling the way you are describing.
When I build such applications, I make sure each active object has its own top-level exception handling block, precisely to prevent the entire application from exploding if one thread fails. Using a platform-specific catch all I think begs for your overall code / solution to be sloppy. I would not use such a thing.
Consider that throwing an exception unwinds the stack. Each thread has its own stack. You will have to place a try/catch block in each thread function (i.e. in the entry point of each thread).
I would like my C++ code to stop running if a certain condition is met, but I'm not sure how to do that. So just at any point if an if statement is true terminate the code like this:
if (x==1)
{
kill code;
}
There are several ways, but first you need to understand why object cleanup is important, and hence the reason std::exit is marginalized among C++ programmers.
RAII and Stack Unwinding
C++ makes use of a idiom called RAII, which in simple terms means objects should perform initialization in the constructor and cleanup in the destructor. For instance the std::ofstream class [may] open the file during the constructor, then the user performs output operations on it, and finally at the end of its life cycle, usually determined by its scope, the destructor is called that essentially closes the file and flushes any written content into the disk.
What happens if you don't get to the destructor to flush and close the file? Who knows! But possibly it won't write all the data it was supposed to write into the file.
For instance consider this code
#include <fstream>
#include <exception>
#include <memory>
void inner_mad()
{
throw std::exception();
}
void mad()
{
auto ptr = std::make_unique<int>();
inner_mad();
}
int main()
{
std::ofstream os("file.txt");
os << "Content!!!";
int possibility = /* either 1, 2, 3 or 4 */;
if(possibility == 1)
return 0;
else if(possibility == 2)
throw std::exception();
else if(possibility == 3)
mad();
else if(possibility == 4)
exit(0);
}
What happens in each possibility is:
Possibility 1: Return essentially leaves the current function scope, so it knows about the end of the life cycle of os thus calling its destructor and doing proper cleanup by closing and flushing the file to disk.
Possibility 2: Throwing a exception also takes care of the life cycle of the objects in the current scope, thus doing proper cleanup...
Possibility 3: Here stack unwinding enters in action! Even though the exception is thrown at inner_mad, the unwinder will go though the stack of mad and main to perform proper cleanup, all the objects are going to be destructed properly, including ptr and os.
Possibility 4: Well, here? exit is a C function and it's not aware nor compatible with the C++ idioms. It does not perform cleanup on your objects, including os in the very same scope. So your file won't be closed properly and for this reason the content might never get written into it!
Other Possibilities: It'll just leave main scope, by performing a implicit return 0 and thus having the same effect as possibility 1, i.e. proper cleanup.
But don't be so certain about what I just told you (mainly possibilities 2 and 3); continue reading and we'll find out how to perform a proper exception based cleanup.
Possible Ways To End
Return from main!
You should do this whenever possible; always prefer to return from your program by returning a proper exit status from main.
The caller of your program, and possibly the operating system, might want to know whether what your program was supposed to do was done successfully or not. For this same reason you should return either zero or EXIT_SUCCESS to signal that the program successfully terminated and EXIT_FAILURE to signal the program terminated unsuccessfully, any other form of return value is implementation-defined (§18.5/8).
However you may be very deep in the call stack, and returning all of it may be painful...
[Do not] throw an exception
Throwing an exception will perform proper object cleanup using stack unwinding, by calling the destructor of every object in any previous scope.
But here's the catch! It's implementation-defined whether stack unwinding is performed when a thrown exception is not handled (by the catch(...) clause) or even if you have a noexcept function in the middle of the call stack. This is stated in §15.5.1 [except.terminate]:
In some situations exception handling must be abandoned for less subtle error handling techniques. [Note: These situations are:
[...]
— when the exception handling mechanism cannot find a handler for a thrown exception (15.3), or when the search for a handler (15.3) encounters the outermost block of a function with a noexcept-specification that does not allow the exception (15.4), or [...]
[...]
In such cases, std::terminate() is called (18.8.3). In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called [...]
So we have to catch it!
Do throw an exception and catch it at main!
Since uncaught exceptions may not perform stack unwinding (and consequently won't perform proper cleanup), we should catch the exception in main and then return a exit status (EXIT_SUCCESS or EXIT_FAILURE).
So a possibly good setup would be:
int main()
{
/* ... */
try
{
// Insert code that will return by throwing a exception.
}
catch(const std::exception&) // Consider using a custom exception type for intentional
{ // throws. A good idea might be a `return_exception`.
return EXIT_FAILURE;
}
/* ... */
}
[Do not] std::exit
This does not perform any sort of stack unwinding, and no alive object on the stack will call its respective destructor to perform cleanup.
This is enforced in §3.6.1/4 [basic.start.init]:
Terminating the program without leaving the current block (e.g., by calling the function std::exit(int) (18.5)) does not destroy any objects with automatic storage duration (12.4). If std::exit is called to end a program during the destruction of an object with static or thread storage duration, the program has undefined behavior.
Think about it now, why would you do such a thing? How many objects have you painfully damaged?
Other [as bad] alternatives
There are other ways to terminate a program (other than crashing), but they aren't recommended. Just for the sake of clarification they are going to be presented here. Notice how normal program termination does not mean stack unwinding but an okay state for the operating system.
std::_Exit causes a normal program termination, and that's it.
std::quick_exit causes a normal program termination and calls std::at_quick_exit handlers, no other cleanup is performed.
std::exit causes a normal program termination and then calls std::atexit handlers. Other sorts of cleanups are performed such as calling static objects destructors.
std::abort causes an abnormal program termination, no cleanup is performed. This should be called if the program terminated in a really, really unexpected way. It'll do nothing but signal the OS about the abnormal termination. Some systems perform a core dump in this case.
std::terminate calls the std::terminate_handler which calls std::abort by default.
As Martin York mentioned, exit doesn't perform necessary clean-up like return does.
It's always better to use return in the place of exit.
In case if you are not in main, wherever you would like to exit the program, return to main first.
Consider the below example.
With the following program, a file will be created with the content mentioned.
But if return is commented & uncommented exit(0), the compiler doesn't assure you that the file will have the required text.
int main()
{
ofstream os("out.txt");
os << "Hello, Can you see me!\n";
return(0);
//exit(0);
}
Not just this, Having multiple exit points in a program will make debugging harder.
Use exit only when it can be justified.
Call the std::exit function.
People are saying "call exit(return code)," but this is bad form. In small programs it is fine, but there are a number of issues with this:
You will end up having multiple exit points from the program
It makes code more convoluted (like using goto)
It cannot release memory allocated at runtime
Really, the only time you should exit the problem is with this line in main.cpp:
return 0;
If you are using exit() to handle errors, you should learn about exceptions (and nesting exceptions), as a much more elegant and safe method.
return 0; put that wherever you want within int main() and the program will immediately close.
The program will terminate when the execution flow reaches the end of the main function.
To terminate it before then, you can use the exit(int status) function, where status is a value returned to whatever started the program. 0 normally indicates a non-error state
Either return a value from your main or use the exit function. Both take an int. It doesn't really matter what value you return unless you have an external process watching for the return value.
If you have an error somewhere deep in the code, then either throw an exception or set the error code. It's always better to throw an exception instead of setting error codes.
Generally you would use the exit() method with an appropriate exit status.
Zero would mean a successful run. A non-zero status indicates some sort of problem has occurred. This exit code is used by parent processes (e.g. shell scripts) to determine if a process has run successfully.
Beyond calling exit(error_code) - which calls atexit handlers, but not RAII destructors, etc.
- more and more I am using exceptions.
More and more my main program looks like
int main(int argc, char** argv)
{
try {
exit( secondary_main(argc, argv );
}
catch(...) {
// optionally, print something like "unexpected or unknown exception caught by main"
exit(1);
}
}
where secondary_main
in where all the stuff that was originally is put --
i.e. the original main is renamed secondary_main, and the stub main above is added.
This is just a nicety, so that there isn't too much code between the tray and catch in main.
If you want, catch other exception types.
I quite like catching string error types, like std::string or char*, and printing those
in the catch handler in main.
Using exceptions like this at least allows RAII destructors to be called, so that they can do cleanup. Which can be pleasant and useful.
Overall, C error handling - exit and signals - and C++ error handling - try/catch/throw exceptions - play together inconsistently at best.
Then, where you detect an error
throw "error message"
or some more specific exception type.
If the condition I'm testing for is really bad news, I do this:
*(int*) NULL= 0;
This gives me a nice coredump from where I can examine the situation.
Dude... exit() function is defined under stdlib.h
So you need to add a preprocessor.
Put include stdlib.h in the header section
Then use exit(); wherever you like but remember to put an interger number in the parenthesis of exit.
for example:
exit(0);
If your if statement is in Loop You can use
break;
If you want to escape some code & continue to loop Use :
continue;
If your if statement not in Loop You can use :
return 0;
Or
exit();
To break a condition use the return(0);
So, in your case it would be:
if(x==1)
{
return 0;
}