Try/catch whole program [closed] - c++

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've taken the habit to construct my C++ projects as follows :
int main(int ac, char* av[])
{
try
{
Object foo;
foo.run()
/* ... */
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
return 1;
}
catch (...)
{
std::cerr << "Unknown error." << std::endl;
return 1;
}
return 0;
}
I wonder if this is a good practice, or is it better to use try/catch blocks on small pieces of codes that are "expected" to produce errors ?

Generally, catching all exceptions is not a good idea: you want to catch only these exceptions that your particular piece of code is ready to handle in a meaningful way.
However, the top-level entry point is an exception from this rule: it is a common practice to catch all exceptions yourself if you wish to control how exceptions are processed on the top level.
A common way of implementing it, however, is to write a single function that looks like main, but has a different name:
int entryPoint(int argc, char *argv[]) {
... // The real logic goes here
Object foo;
foo.run()
/* ... */
}
Your code looks like this, and never changes:
int main(int ac, char* av[])
{
try
{
return entryPoint(ac, av);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::cerr;
}
catch (...)
{
std::cout << "Unknown error." << std::endl;
}
}

You can put your whole program into such a top-level exception-handler, if you want to control how unhandled exceptions are handled (if they reach top-level).
There is a dis-advantage to that though: The standard crash-behavior is pre-empted, which probably means you get no crash-dumps, and thus are missing crucial information for post-mortem debugging.
Also, they might not reach top-level, but result in std::unexpected() and by that std::terminate() being called.
Thus, you might be better served by std::set_terminate even if you want to do your own thing.
Consider doing your own thing and then crashing like normal (Which you cannot do with your global exception-handler).

The advantage is your program never crashing (on Linux it can crash tough, since signals can't be caught as exceptions)
But there is one disadvantage I can think of: When you debug your code and have a run time error, you don't know where it was or see the stack. since your program continue running from the catch. so instead of check immediately what happened you need to run again and hope you'll have the same behavior.
Another thing: if your program is Multi-threaded, it won't help to caught all exceptions, since each thread need to catch his own exceptions.

It's certainly better to try/catch as near the throw as possible if you can do something to recover from the error. Catching every fatal error on the other hand may clutter your code quite a bit.
If a throw is not caught, std::terminate will be called and you can set that function to a custom one with std::set_terminate. Inside the terminate function, you can do throw; which rethrows the uncaught object and then catch it. You must use catch(...) at the end in this case, since throwing from the terminate function is not a good thing.

Yes surely it would make difference...Let's see how.
try
{
// code which could throw an exception
}
catch(Myexception& e) //derived from std::exception
{
//do something.
}
//..some more code. //Point_1
Let's say I just want to do some manipulation after catching Myexception then then resume this function. After catching the exception code would come to POINT_1. Had I encapsulated this in try/catch it would have been ignored.

Related

Is it important that what() does not throw (exception classes)?

An exercise from C++ Primer asks
Why is it important that the what function [of exception classes] doesn’t throw?
Since there is no way to check my answer I was hoping to get an opinion. I thought possibly that it is an error (maybe terminate would've been called) to throw another exception during a catch clause (other than a rethrow throw;) while the current exception object is still being handled. It seems that is not the case though and it is completely okay to throw out of catch clauses:
#include <iostream>
using namespace std;
int main(){
try{
try{
throw exception();
} catch(exception err){ throw exception();}
} catch(exception err){ cout << "caught"} //compiles and runs fine, outputs "caught"
}
So program terminations are not a worry. It seems then, any problem that arises from what() throwing should, at the very least, be rectifiable by the user if they were so inclined.
Maybe then, the importance might be that while handling an error we do not want further unexpected errors to occur? Throws inside catch clauses are mainly intended for sending the exception object further up the call chain. A user may receive an error from deep in his program and does not want to worry that the error caught has to be associated with its own try block. Or maybe what() having its own throw may also lead to recursive effects (e.g. what() throws an exception, then we catch this exception and call what() but this then throws, and so on) meaning it might become impossible to handle any errors? How drastic can it be for what() to potentially throw?
I think there's nothing unclear - it's just as you described. If .what() method of an exception class throws an error, the whole catch effort was wasted:
try {
someDangerousOperation();
}
catch(std::exception e) {
// Ooops, instead of false,
//we get another exception totally unrelated to original error
someLogClassOrWhatever.save(e.what());
return false;
}
return true;
And Imagine the crazy code if you were expected to deal with what()'s exceptions:
try {
someDangerousOperation();
}
catch(std::exception e) {
// Not very fun
try {
someLogClassOrWhatever.save(e.what());
}
catch(...) {
alsoWhatHasFailedThatIsReallyGreat();
}
return false;
}
I think there's nothing more in that, probably the question is so simple it seems there must be some catch hiding in it. I think it's not the case.
std::exception::what() is noexcept. Consequently, if it throws, std::terminate is called. Yes, this is important.
Image a very curious coder with a slight tendency towards being a control freak (I know a couple of them myself), he really wants to know what is going wrong in his program and logs all errors with ex.what(). So he codes
try {
code();
}
catch(std::exception &e) {
std::cout<<e.what()
}
He is pretty pleased with the world in general and with himself in particular. But now it crosses his mind, that e.what() could throw an exception as well. So he is codes:
try{
try {
code();
}
catch(std::exception &e) {
std::cout<<e.what()
}
}
catch(std::exception &e) {
std::cout<<e.what()
}
A minute later he notices, that there is again an uncaught exception possible! Remember, he is a control freak, so he is going to write another try-catch block and than another and another
So you can bet any money, his project will be late - how could you do something like this to my friend? So please make sure e.what() doesn't throw:)
I guess it is the reason behind what being noexcept.

Is this C++ code defining main or running main?

I'm reading Stroustrup's Programming: Principles and Practice and came across this code:
int main()
try {
// our program
return 0; //0 indicates success
}
catch (exception& e) {
cerr << "error: " <<e.what() <<'\n';
keep_window_open();
return 1; // 1 indicates failure
}
catch (...) {
cerr << "Oops: Unknown exception!\n";
keep_window_open();
return 2; //2 indicates failure
}
At first I thought that the first line called the main function (which contained the heart of the code and was written somewhere else). And then we are just trying to catch errors that might have occurred inside of main(). But if that's the
case, why does it say "our program" in the try block? This makes me think that
this code is defining main(). But if that's the case, then where are the bracket
s? That is, why isn't it int main() { on the first line?
int main()
try
{
}
catch (...)
{
}
...optionally more catches...
...is just a shorter notation equivalent to...
int main()
{
try
{
}
catch (...)
{
}
...optionally more catches...
}
Why does it exist? Well:
As soon as you see the function, you understand that a try/catch block encompasses all the function content, whereas in the second form you have to scan down to the end to see if there's anything after the catches. This insight makes it quicker and easier to reason about the exception handling.
With the second notation, another programmer's more likely to unwittingly insert code before or after the try/catch block, which may invalidate earlier exception handling design. A try/catch block makes it more obvious that "encompassing" exception handling is a deliberate design decision.
It's more concise.
If you have an existing function and want to add exception handling to it, then using the function try block notation clearly avoids having to indent everything inside the function to continue to comply with normal indentation practices. Indenting an entire function is painful, especially if you observe an 80 (or whatever) character line length and have to manually wrap long lines to get them formatted the way you want. (Similarly, if you had a catch statement then decide to let the exceptions directly reach the caller - obviously more useful for functions other than main - you can remove the try/catch without needing to unindent the try { } content.)
It defines the main() function using function-try-block:
When is a function try block useful?

Function-body exceptions [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Difference between try-catch syntax for function
What is the difference in the utility and behavior of these try-catch blocks? When would I prefer one form over the other?
int f() {
try {
...
} catch(...) {
...
}
}
int f() try {
...
} catch (...) {
...
}
If the entire body must go into the exception block, I tend to prefer the 2nd form as it's easier to read (e.g. one less indentation level).
However, the main place where this makes a difference is in constructors. Consider:
Foo::Foo ()
try : member_with_throwing_constructor(initial_value)
{
}
catch ( ... )
{
// will process exceptions thrown by `member_with_throwing_constructor`
// this will be added by the compiler if you
// don't finish by a `throw ...` statement.
throw;
}
and
Foo::Foo ()
: member_with_throwing_constructor(initial_value)
{
try
{
}
catch ( ... )
{
// does not catch exceptions thrown in constructor
// of `member_with_throwing_constructor`.
}
// can keep processing if `catch` handler does not `return` or `throw`.
}
These two code snippets have radically different behavior. The first one will catch exceptions raised in data member constructors (usually through the initializer list, but default constructors apply too) and will automatically re-raise the exception because the instance could not be created safely. The second form does not cover data member initialization and allows you to choose whether to keep the object or not.
I also like to add a global try-catch in main() to help with debugging uncaught exceptions. The following snippet:
int main ( int, char ** )
try
{
// main program...
}
catch ( const std::exception& error )
{
std::cerr << "Uncaught exception: '" << error << "'." << std::endl;
return (EXIT_FAILURE);
}
catch ( ... )
{
std::cerr << "Uncaught exception of unknown type." << std::endl;
return (EXIT_FAILURE);
}
Some people will argue that not catching the exceptions allows the program to crash and you can get a core dump to help with debugging. While this may be useful in debug mode, as it can help the debugger point you to the exact line of code that raised the exception, I like to ship programs that don't crash, and I can show the user a message saying a bug report was submitted.
Function try-catch blocks are only useful in constructors, and even then, not very useful at all. It's best to just forget they exist.

ellipsis try catch on c++

Can an ellipsis try-catch be used to catch all the errors that can lead to a crash? Are there are any anomalies?
try
{
//some operation
}
catch(...)
{
}
No, it'll only catch C++ exceptions, not things like a segfault, SIGINT etc.
You need to read up about and understand the difference between C++ exceptions and for want of a better word, "C-style" signals (such as SIGINT).
If the code inside try/catch block crashed somehow, the program is anyway in a non-recoverable state. You shouldn't try to prevent the crash, the best that the program can do is just let the process crash.
The "anomaly" is in the fact that your code only catches the exceptions, and not the errors. Even if the code is exception-safe (which may be not the case, if you are trying to work-around its mistakes by a try/catch block), any other inner error may bring the program into irrecoverable state. There is simply no way to protect the program from it.
Addition: look at this article at "The Old New Thing" for some insights.
It is the Catch All handler.
It catches all the C++ exceptions thrown from the try block. It does not catch segfault and other signals that cause your program to crash.
While using it, You need to place this handler at the end of all other specific catch handlers or it all your exceptions will end up being caught by this handler.
It is a bad idea to use catch all handler because it just masks your problems and hides the programs inability by catching all(even unrecognized) exceptions. If you face such a situation you better let the program crash, and create a crash dump you can analyze later and resolve the root of the problem.
It catches everything that is thrown, it is not limited to exceptions. It doesn't handle things like windows debug asserts, system signals, segfaults.
TEST(throw_int) {
try {
throw -1;
} catch (std::exception &e) {
std::cerr << "caught " << e.what() << std::endl;
} catch (...) {
std::cerr << "caught ..." << std::endl;
}
}
Throwing an integer isn't really recommended though. It's better to throw something that inherits from std::exception.
You might expect to see something like this as a last ditch effort for documenting failure, though. Some applications aren't required to be very robust. Internal tools might cost more than they are worth if you went through the paces of making them better than hacked together crap.
int main(int argc, char ** argv) {
try {
// ...
} catch (std::exception &e) {
std::cerr << "error occured: " << e.what() << std::endl;
return 1;
}
return 0;
}

what does "throw;" outside a catch block do?

I just stumbled this code:
void somefunction()
{
throw;
}
and I wonder: what does it mean?
The intent is probably that somefunction() is only ever called from inside some catch block. In that case, there would be an exception active when the throw; is executed, in which case the current exception is re-thrown, to be caught by the next outer handler that can handle that exception type.
If throw; is executed when an exception is not active, it calls terminate() (N4810, §[expr.throw]/4).
It re-throws the currently active exception. It would only make sense to call it (possibly indirectly) from a catch-block. This:
#include <iostream>
using namespace std;
void f() {
throw;
}
int main() {
try {
try {
throw "foo";
}
catch( ... ) {
f();
}
}
catch( const char * s ) {
cout << s << endl;
}
}
prints "foo".
For throw the concept of being "outside" or "inside" catch block is defined in run-time terms, not in compile-time terms as you seem to assume. So, if during run-time that throw is executed in run-time context of a catch block, then throw works as expected. Otherwise, terminate() is called.
In fact, if you take a closer look at how C++ exceptions are defined in the language specification, a lot of things about them are defined in run-time terms. Sometimes it even appears to be un-C++-like.
People have already explained what it means but it's potentially useful to know why you might see it. It's a useful way to construct a 'generic' exception handler that deals with exceptions based on their type so as to reduce the amount of duplicated code.
So, if we take Neil's example and expand on what f() might be doing we might end up with an implementation which does something like my LogKnownException() function that I proposed in this answer.
If you are working in an team that likes to log all manner of exceptions all over the place then rather than having a huge collection of catch blocks at all of these places (or even worse a macro) you can have a simple catch block that looks like this
catch(...)
{
LogKnownException();
}
Though I expect I'd change my previous example of LogKnownException() to one that simply allowed exceptions that it didn't want to log to propagate out and continue on in an unhandled fashion.
I'm not suggesting that this is necessarily a good thing to do, just pointing out that this is where you're likely to see the construct used.