The below given simple exception program is giving Unhandled Exception "Microsoft C++ exception: int at memory location 0x0012fe94..". I am getting this error immediately after the function excep() is returned.
Please can anyone tell why this error is coming here. Also it will be helpful if all the possible mistakes in this code were explained/analysed. I am learning to code better.
I am using Visual C++ 2005.
#include <iostream>
using namespace std;
int main ()
{
int excep(int);
throw excep(20);
return 0;
}
int excep(int e)
{
cout << "An exception occurred. Exception Nr. " << e << endl;
return 0;
}
If you try to learn exception throwing/handling your code contains an error.
function excep must handle object that was thrown not to be thrown itself.
your code must be rewritten as follows:
using namespace std;
int excep(int e)
{
cout << "An exception occurred. Exception Nr. " << e << endl;
return 0;
}
int main ()
{
int excep(int);
try
{ // <--------- Begin of try block. required part of the exception handling
throw 20;
}
catch (const int &errCode) // <------- we are catching only ints
{
excep(errCode); // Function that handles exception
}
return 0;
}
It is good design not to throw int variables, but type that inherites std::exception. But this is more advanced exception using knowledge
What did you expect to happen?
You call a function which prints out "An exception occurred", plus the other text, and then you throw the resulting value as an exception, which you never catch, so the program reports than an uncaught exception was thrown. Which is true, because that's exactly what you just did.
The entire point in exceptions is that when you throw an exception, it will propagate out through the program, until it is either handled, or it reaches the top level and terminates the program. You don't handle the exception, so it terminates the program.
If you want to handle an exception, you need to wrap the throwing code in a try block, followed by a catch, as in:
try {
throw excep(20);
}
catch (int ex) {
// do something about the exception
}
In the line
throw excep(20);
excep(20) is called first, whose return value is then thrown, i.e. you throw an integer. It is roughly equivalent to:
const int i = excep(20);
throw i;
To get you an idea how exception-snytax looks:
#include <iostream>
#include <stdexcept>
using namespace std;
int main ()
{
try {
// do something
throw std::runtime_error("test");
} catch (const std::exception &e) {
std::cout << "exception: " << e.what() << std::endl;
}
}
In practive: NEVER throw anything that is not derived from std::exception.
Proposed Readings:
Introductory book on C++ (search stackoverflow for this)
C++ FAQ on Exception Handling
"Exceptional C++" (for advanced C++ users)
Related
When an exception is thrown, it would be nice to be able to add information about how the error could happen, as the exception propagates up the call stack.
With information i don't mean technical info (e.g. Error in /src/foo.cpp:26), but something in context of the domain (e.g. Failed to load image "foo.png").
So instead of tracing the actual call stack, i want to provide my own information.
What's the best way to implement that in c++11?
I tried using nested exceptions with std::throw_with_nested() but the problem there is that if you want to catch some exceptions by their type only the outermost exception can be caught (I want the innermost).
Like in this example:
#include <iostream>
#include <exception>
void run()
{
try
{
throw 1;
}
catch(...)
{
std::throw_with_nested(std::runtime_error("run() failed"));
}
}
int main()
{
try {
run();
} catch(const int& e) {
// won't handle this error because only outermost exception can be caught
std::cerr << e << std::endl;
}
}
That is a problem, because the outer exceptions are only there to provid informartion, and only the innermost represents the actual error.
Try/catch block in C++ not being "caught."
I'm trying to have one catch block to get all exceptions.
#include <iostream>
#include <exception>
using namespace std;
int main()
{
try
{
throw 1;
}
catch (exception& e)
{
cout << "ERROR: " << e.what() << endl;
return 1;
}
return 0;
}
throw 1; will throw an int. As you do not catch an int, the exception goes uncaught, which is undefined behavior. Though it is possible to throw anything, always prefer to throw a class that derives from std::exception. You can catch an int with catch(int e) or catch(...), but there's really no reason to ever do that.
If you catch with catch(...), then you do not know the type of the object, so cannot access any members, properties, or other aspects, and so you cannot* gather any information about what was thrown. This should never be used.
*There are ways to get information about the thrown object, but it's far easier to just catch the right type in the first place
You are throwing an int, but only catching std::exception. Use a catch(...) to catch everything thrown.
#include <iostream>
using namespace std;
class Cls
{
public:
~Cls()
{
throw "exp";
}
};
int main()
{
try
{
Cls c;
throw "exp";
}
catch (...)
{
cout << "Why this doesn't call" << endl;
}
}
When I execute this code, it doesn't goes in catch block. And give following exception,
But, when I run this code with little modification, it goes to catch block.
int main()
{
try
{
throw "exp";
throw "exp";
}
catch (...)
{
cout << "Why this doesn't call" << endl;
}
}
Output:
Both the above code throws 2 exception, then why Compiler is biased in destructor's case?
In the first case you first throw from the try block and then the stack unwinding throws from Cls's destructor. So you have two exceptions to be handled. C++ handles this situation by calling terminate.
Because of the peculiarity of throwing from destructors, C++11 defines that all destructors are noexcept by default. Then even if there is no other exception to be handled, the exception from a destructor will cause terminate to be called.
The second case is OK because as soon as you throw the first exception try block is left and the exception is handled in the catch block.
What does throw do when not used with try and catch? Like:
if (IsEmpty()) throw "Stack is empty, Cannot delete";
Does it get printed in console?
But when throw contains some int or char as its arguments, it is thrown to catch; what happens in this case?
The C++ runtime will have something along the lines of (this is NOT exactly how it looks, but you can think of it as working this way, unless you are working on something very special):
void BeforeMain()
{
try
{
int res = main();
exit(res);
}
catch(...)
{
cout << "Unhandled exception. Terminating..." << endl;
terminate();
}
}
You are allowed to do that, and it will not be caught anywhere within your code if you have not put an explicit try catch block.
Windows uses a SEH mechanism to handle , where you could have an uncaught exception filter to figure out about the same
See this post for more details
Catching exceptions thrown without try/catch
const int MIN_NUMBER = 4;
class Temp
{
public:
Temp(int x) : X(x)
{
}
bool getX() const
{
try
{
if( X < MIN_NUMBER)
{
//By mistake throwing any specific exception was missed out
//Program terminated here
throw ;
}
}
catch (bool bTemp)
{
cout<<"catch(bool) exception";
}
catch(...)
{
cout<<"catch... exception";
}
return X;
}
private:
int X;
};
int main(int argc, char* argv[])
{
Temp *pTemp = NULL;
try
{
pTemp = new Temp(3);
int nX = pTemp->getX();
delete pTemp;
}
catch(...)
{
cout<<"cought exception";
}
cout<<"success";
return 0;
}
In above code, throw false was intended in getX() method but due to a human error(!) false was missed out. The innocent looking code crashed the application.
My question is why does program gets terminated when we throw "nothing”?
I have little understanding that throw; is basically "rethrow" and must be used in exception handler (catch). Using this concept in any other place would results into program termination then why does compiler not raise flags during compilation?
This is expected behaviour. From the C++ standard:
If no exception is presently being
handled, executing a throw-expression
with no operand calls
terminate()(15.5.1).
As to why the compiler can't diagnose this, it would take some pretty sophisticated flow analysis to do so and I guess the compiler writers would not judge it as cost-effective. C++ (and other languages) are full of possible errors that could in theory be caught by the compiler but in practice are not.
To elaborate on Neil's answer:
throw; by itself will attempt to re-raise the current exception being unwind -- if multiple are being unwound, it attempts to rethrow the most recent one. If none are being unwound, then terminate() is called to signal your program did something bogus.
As to your next question, why the compiler doesn't warn with throw; outside a catch block, is that the compiler can't tell at compile-time whether the throw; line may be executing in the context of a catch block. Consider:
// you can try executing this code on [http://codepad.org/pZv9VgiX][1]
#include <iostream>
using namespace std;
void f() {
throw 1;
}
void g() {
// will look at int and char exceptions
try {
throw;
} catch (int xyz){
cout << "caught int " << xyz << "\n";
} catch (char xyz){
cout << "caught char " << xyz << "\n";
}
}
void h() {
try {
f();
} catch (...) {
// use g as a common exception filter
g();
}
}
int main(){
try {
h();
} catch (...) {
cout << "some other exception.\n";
}
}
In this program, g() operates as an exception filter, and can be used from h() and any other function that could use this exception handling behavior. You can even imagine more complicated cases:
void attempt_recovery() {
try{
// do stuff
return;
} catch (...) {}
// throw original exception cause
throw;
}
void do_something() {
for(;;) {
try {
// do stuff
} catch (...) {
attempt_recovery();
}
}
}
Here, if an exception occurs in do_something, the recovery code will be invoked. If that recovery code succeeds, the original exception is forgotten and the task is re-attempted. If the recovery code fails, that failure is ignored and the previous failure is re-throw. This works because the throw; in attempt_recovery is invoked in the context of do_something's catch block.
From the C++ standard:
15.1 Throwing an exception
...
If no exception is presently being
handled, executing a throw-exception
with no operand calls terminate()
The reason the compiler can't reliably catch this type of error is that exception handlers can call functions/methods, so there's no way for the compiler to know whether the throw is occurring inside a catch. That's essentially a runtime thing.
I have little understanding that throw; is basically "rethrow" and must be used in exception handler (catch). Using this concept in any other place would results into program termination then why does compiler not raise flags during compilation?
Rethrowing is useful. Suppose you have a call stack three levels deep with each level adding some context resource object for the final call. Now, when you have an exception at the leaf level, you will expect some cleanup operation for whatever resources the object has created. But this is not all, the callers above the leaf may also have allocated some resources which will need to be deallocated. How do you do that? You rethrow.
However, what you have is not rethrow. It is a signal of giving up after some failed attempts to catch and process any and all exceptions that were raised.
A throw inside of a catch block with no args will re-throw the same exception that was caught, so it will be caught at a higher level.
A throw outside of a catch block with no args will cause a program termination.
To complete the previous answers with an example of when/why the compiler cannot detect the problem:
// Centralized exception processing (if it makes sense)
void processException()
{
try {
throw;
}
catch ( std::exception const & e )
{
std::cout << "Caught std::exception: " << e.what() << std::endl;
}
catch ( ... )
{
std::cout << "Caught unknown exception" << std::endl;
}
}
int main()
{
try
{
throw 1;
}
catch (...)
{
processException(); // correct, still in the catch clause
}
processException(); // terminate() no alive exception at the time of throw.
}
When compiling the function processException the compiler cannot know how and when it will be called.
You don't have anything to catch, and so the exception bubbles all the way up. Even catch(...) needs something.