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

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?

Related

Try/catch whole program [closed]

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.

Catching all errors

In my program I want to catch every error in a function. I've tried using a try/catch but the program still exits. I've set up an example of what I want to catch
#include <iostream>
#include <stack>
using namespace std;
int main()
{
stack<string> test;
test.push("lel");
try {
test.pop();
test.pop();
}
catch (...) {
cout << "Caught" << endl;
}
return 0;
}
This still causes the program to exit. How can I catch any error, or if it's not possible, this specific error?
stack::pop() does not throw any exception when the stack is empty. Rather it is undefined behavior to pop from an empty stack. Since no exception is thrown, your catch clause can not catch anything, rather program terminates ( anything can happen in UB).
So about your intention of catching all error, I think it is good practice to put a try-catch in mainto catch anything that escaped from any other place, and you should be able to catch if exception is actually being thrown. Just take care of some issues:
Control may not reach in your catch block in case of any UB.
C++ can not handle more than one exceptions simultaneously, in that case program will most likely terminate in place where it happens (specially be careful so that exception does not leave any destructor).
Throwing exception that is not in exception specification list of a function (most likely program will terminate).
The std::stack::pop function is defined by C11++ §23.6.5.2 as
void pop() { c.pop_back(); }
Table 101 in C++11 §23.2.3/16 places the following requirement on a call to pop_pack:
” Requires: a.empty() shall be false.
This means that the call to pop on an empty stack breaks the function's contract, and therefore has Undefined Behavior.
There is no portable way to detect the effect, whatever it turns out to be for your C++ implementation and particular run of the program. But with a given C++ implementation it may be more clearly defined and there you may be able to catch it.

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.

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.

A strange problem with C++ exception handler

I used standard exception handling methods in C++. Which is try{} and catch{} block. In my code, func1() would throw an exception, And func2 is like this:
bool func2()
{
try{
func1();
}
catch(myException& e)
{
cerr << "error!" << endl;
return false;
}
return true;
}
But when I run my code, a strange thing happens. I never reached the code of throwing the exception, but I always reached the line of return false in catch block (but the line of cerr << is never reached either). Then the function continue to return true. I don't know what the reason is. Can anyone help me to figure the problem out? Thank you very much!
If you're using any optimize flags in your compiler (i.e. not debug mode), you can't trust the debugger to show you the proper lines of execution. You've made contradictory statements - the "return false" statement is executing, but the function is returning true. This is the only explanation I can think of.
As #Mark Ransom said, you are probably with optimization enabled. To help you understand what is goind on, this is the C++ equivalent of the code the compiler is probably generating:
bool func2()
{
bool ret;
try{
func1();
ret = true;
}
catch(myException& e)
{
cerr << "error!" << endl;
ret = false;
}
return ret;
}
However, when you are at the return ret; "line" on the generated code, there are two lines in the original code you could actually be in: return false; and return true;. The debugger has no idea which is the correct one, and so it displays the first one (actually, it is the compiler when generating the tables the debugger will use which makes the choice).
This will be much more obvious if you tell the compiler to generate an assembly file and look at it. Assuming this is x86, where the return value is on %eax, both branches will be setting %eax to either 1 or 0 and then jumping or falling through to the common function epilogue code (which is where it will actually return from the function).
Open your app in WinDbg (or gdb), and enable first chance exceptions (in WinDbg via sxe eh).
How do you know it reached the return false? If func2 didn't do the cerr and returned true, it sounds like no exception was caught and the return false wasn't executed.
If you are using a debugger, sometimes it will show that you are on the closing brace for the catch block when no exception is thrown, which might be confusing.
If you're hitting the return true statement is another type of exception being thrown? Try adding a catch(...).
I've noticed sometimes cerr can act werid, have you tried replacing the cerr with a cout? Also just try putting two cout's within the exception block.
If no output is being produced and the function is RETURNING true.
Then no exception is escaping func1().
As a result the function returns true.
But what you may be experiencing is the de-buggers inability to map machine instructions back to C++ source after the code has been optimized (as the optimizer may re-arrange the code).
I suggest you try somthing like the below to make sure you are reporting all exceptions.
Try this:
bool func2()
{
try
{
func1();
}
catch(MyException const& e)
{
std::cerr << "Error!: Cought My Exception\n";
return false;
}
catch(...) // Catch any other exceptions
{
std::cerr << "Error!: Unknown Exception detected\n";
/*
* To keep the same functionality of your original code
* Rethrow the unknown exception.
*/
throw;
}
return true;
}
Use Debug mode, not optimized mode. Also, make sure that you aren't writing to any dangling pointers.