I a couple of C++ examples I've seen throw 1 in catch block. Tried to find out what it may be, but always found a classical example with exception object or rethrowing an exception without any argument.
Also sometimes I can find in Internet other examples, also without explanations:
throw 1
throw 2
throw -1
Tell me please what it may mean.
Tell me please what it may mean.
It means you're throwing a value of a int that has the value 1, 2 or -1.
Of course, without any further detail, it's hard to infer a meaning on this.
A use case would be to report error code from a function:
int returning_error_code() {
try {
stuff();
} catch (int e) {
return e; // return error code
}
return 0; // no error
}
throw 1
throw 2
throw -1
Tell me please what it may mean.
throw throws an object. throw 1 throws an object if type int with the value 1. I assume the reader can extrapolate what the other two mean.
This is an exception mechanism. The thrown object can be caught:
try {
throw 1;
} catch (int e) {
std::cout << "an integer was thrown and caught. here is the value: " << e;
}
I've seen throw 1 in catch block.
Throwing inside an exception handler is allowed. It has same behaviour as throwing outside a handler.
always found a classical example with exception object or rethrowing an exception without any argument.
This is a case of throwing an exception object.
There is no limitation to the type of objects that can be thrown. The standard library follows the convention of throwing only classes derived from std::exception. Following this convention in user programs is recommended.
Related
This question already has answers here:
Nested try...catch inside C++ exception handler?
(2 answers)
Closed 1 year ago.
Consider the following C++ code:
class MyException {};
void someFunction()
{
try
{
/// ... code that may throw
}
catch(std::exception& e )
{
throw MyException();
}
}
Question
Is the exception e absorbed at the beginnging of the catch block or at the end of the catch block?
In the second case throwing the new exception would result in having two exceptions in flight, what is not what I want. I want to absorb the std::exception and start one of my own type.
No. That's how one should do it. The throw myException() can only occur if the first exception has been caught and hence is no longer 'in flight'.
This design pattern is quite common to 'translate' error messages coming from another library that your code is using to an error that the user of your code can better relate to.
Alternatively, if you want to do more than merely throw (say you want to do some clearing up of resources -- though that should really be done via RAII, i.e. from destructors), then you can simply rethrow the original exception via
try
{
// ... code that may throw
}
catch(...) // catches anything
{
// ... code that runs before rethrowing
throw; // rethrows the original catch
}
just throw; statement is enough in catch block to rethrow same exception in higher context.
It throws SAME exception again. No new exception is generated. So no fight :)
In case you want to catch exception of type A and then throw exception of type B, then the way you did it is absolute correct.
In this case, old exception (type A) is caught(absorbed) and only new exception(type B) is thrown to higher context. So, again no fight :)
I'm reading the "C++ Programming Language 4th edition" book and have a question regarding a paragraph about exception handling:
There are cases where exception handling must be abandoned for less
subtle error-handling techniques. The guiding principles are:
Don't throw an exception while handling an exception.
Don't throw an exception that can't be caught.
If the exception-handling implementation catches you doing either, it
will terminate your program.
Could someone give me an example of the first situtation? Only something like this comes to my mind but it's a valid code according to g++:
try
{
throw 1;
}
catch(...)
{
try
{
throw 2;
}
catch(...)
{
cout << "OK";
}
}
That's a bit misleading; it's fine to throw from an exception handler (which is what I'd understand by "while handling an exception"), as long as there's another handler to catch it.
The problem is if you throw an exception from the destructor of an object that's being destroyed during stack unwinding. In that case, there are two unhandled exceptions, and the usual exception mechanism can only deal with one; so the response is to call terminate.
Example:
struct dodgy {~dodgy() {throw "Don't do this!";}};
try {
dodgy d;
throw 1;
} catch (...) {
// Never reached: destroying `d` killed the program.
}
Learning "try & catch". What is wrong with the following code?
Thanks for the advice.
Error in execution:
terminate called without an active exception
Aborted
The code:
#include <stdio.h>
int main()
{
int a = 3;
try
{
if (a < 5)
throw;
}
catch (...)
{
printf ("captured\n");
}
return 0;
}
Your throw; statement tries to rethrow a current exception but there probably isn't one. You need something like
throw some_exception_object();
Inside of a try block, you have to specify what to throw. The only place you can use throw by itself is inside of a catch block to re-throw the current exception. If you call throw by itself without a current exception being active, you will kill your app, as you have already discovered.
Try this:
#include <stdio.h>
int main()
{
int a = 3;
try
{
if (a < 5)
throw 1; // throws an int
}
catch (...)
{
printf ("captured\n");
}
return 0;
}
You can throw anything you want, as long as you throw something.
There are four things, two major and two minor. One thing at a time...
1. Rethrow usage w/o active exception
A throw; statement is used to re-throw an exception that is currently caught. For example:
try {
do_something();
} catch (const std::exception &) {
throw; // This statement re-throws an exception that was caught in this "catch" block.
}
In your case, you are using throw; without catching any exceptions (in order words — it does not appear inside catch block directly or indirectly), thus your program is terminated. When there is a need to throw and not to re-throw an exception, like in your case, you must specify an exception object to be thrown. For example:
throw std::runtime_error("Something bad happened");
2. catch-all clause which does not re-throw a caught exception
Your catch-all clause (catch (...)) is perfectly legal C++. However, it does not re-throw caught exception. Even though it is a legal C++ code, such a usage is a taboo. C and C++ runtime is usually using special types of exceptions to implement certain functionality. For example, NPTL is using exceptions to implement a thread cancellation. If you catch that exception using catch (...), a thread won't be cancelled and you are going to have a bad time. Generally, you have to catch exceptions by their types. In almost all cases, exceptions are inherited from std::exception, and so you have to write catch (const std::exception &) or, if you expect to catch an exact type, - catch(const TypeYouExpect &). If you must, however, use catch-all, remember to re-throw. For example:
try {
do_something();
} catch (...) {
throw; // DO NOT FORGET TO RE-THROW.
}
3. Header naming...
You are including C header whereas C++ provides its own headers for standard C features. So, header:
#include <stdio.h>
.. should be:
#include <cstdio>
C++ specific C functions get special treatment. For example, they become available in std namespace. So that you can use std::open() instead of just open() or ::open(). No big deal, but is highly recommended way to go.
4. Return from main.
Unlike C, C++'s main() function is very special. It allows you not to have return 0;. This is a default behavior. So, unless you really need to return some value, you may save yourself some time by not typing return 0;. Remember, however, that main is the only function like that, and that everywhere else you must explicitly return something unless a function is marked void.
Hope it helps. Good Luck!
You need to actually throw some object. Even something as simple as
throw "error";
will catch the error like you want it to.
see it in action here
The statement to throw an exception is:
throw <expression>;
This statement:
throw;
is also called the re-throw statement and is use to re-throw an existing exception that has been caught. It is typically used in a catch block, for example, you look at the exception and decide if you can continue, retry or abort. In case you decide to abort, you re-throw the exception so that somebody else down the call stack will catch it and handle this error.
For example:
// getResult() calls can fail with a deadlock exception
// This method will retry up to 3 times before failing
Result getResultWithRetry()
{
int nbTry = 3;
for(;;) {
try {
return getResult();
} catch (DeadLockException& e) {
if (nbTry == 0) {
throw; // re-throw the deadlock exception
}
}
--nbTry;
}
}
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.
int main ()
{
try
{
try
{
throw 5;
}
catch (int n)
{
throw;
}
}
catch (...)
{
cout << "Exception occurred";
}
}
This prints out "Exception occured" but
int main ()
{
try
{
try
{
throw;
}
catch (...)
{
throw;
}
}
catch (...)
{
cout << "Exception occurred";
}
}
This just errors. It seems like I'm doing the try-catch's exactly the same! The only difference is that in the first case I'm throwing an int, then a general exception, but in the second case, I'm throwing a general exception both times. Is the program confused as to which catch to go to?
There's no such thing as "general exception" and you throw no such thing.
In the first example, you throw an int, then you re-throw the exception that you are handling. That's the meaning of throw without an argument.
In the second example you start with an attempt to re-throw an exception that you are handling. As you are not handling an exception at that time, you get an error.
Your 2nd example terminates the program with a good error message (at least using g++ 4.6.1):
terminate called without an active exception
Aborted
This happens because you are trying to re-throw an exception, but since there are no active exception, the program terminates.
The current c++11 draft, in chapter 15.5.1 says this:
In some situations exception handling must be abandoned for less
subtle error handling techniques.
Then in the list of cases when std::terminate is called is this:
when a throw-expression with no operand attempts to rethrow an
exception and no exception is being handled (15.1),
So, the behavior from your 2nd example is well defined in the standard.