Orphan code block throwing Exception in struct - c++

I was recently asked this question in an interview. Below code, snippet behavior was asked. I mentioned that the code would
throw an exception that would be caught but it did not turn out to be the right answer.
I have tried debugging this piece of the code snippet and have two questions.
1.
If execution does enter the line try { A a; } then why catch fails to catch the exception?
2.
What is the behavior of this orphan piece of code that does not belong to any method inside the struct? If I put the orphan code
to be included under the constructor method of B i.e inside B() { } then the exception is caught properly. so how does the execution
flow handle this? I mean to which method/function stack does the orphan code try catch in B belong?
#include<iostream>
#include<string>
using namespace std;
struct A
{
A()
{
throw 2;
}
};
struct B
{
B()
// start of orphan code.
try
{
A a;
}
catch(int i)
{
cout << i << endl;
}
// end of orphan code.
};
int main(int argc, char* argv[])
{
B b;
cout << "3" << endl;
return(0);
}

What you call "orphan code" is in fact a function try block. Such blocks have a special behavior when used with constructors and destructors: every catch block implicitly rethrows the exception, as if the last statement were throw; . This is done to make it impossible to use an object that failed to complete construction.

Related

Why C++ biased towards destructor's exception?

#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.

exception handling, unexpected terminator in c++

Following code is about exception handling. I got the output:
Botch::f()
I'll be back!
Why Fruit is not caught? Thanks!
Ignore this. I think I have provided enough detail.
#include <exception>
#include <iostream>
using namespace std;
void terminator() {
cout << "I'll be back!" << endl;
exit(0);
}
void (*old_terminate)() = set_terminate(terminator);
class Fruit {};
class Botch {
public:
void f() throw(Fruit, bad_exception) {
cout << "Botch::f()" << endl;
throw Fruit();
}
~Botch() { throw 'c'; }
};
int main() {
try{
Botch b;
b.f();
} catch(Fruit&) {
cout << "inside catch(Fruit)" << endl;
} catch(bad_exception&) {
cout << "caught a bad_excpetionfrom f" << endl;
}
}
Because during stack unwinding for your Fruit exception you threw another exception (from the Botch destructor). So your terminator was called instead. This is why throwing exceptions from a destructor is a bad idea,
Fruit is not caught because the code never reaches that catch clause. In the try block in main, the call to b.f() throws an exception of type Fruit. In response, the code destroys the Botch object before entering the catch clause. The destructor of Botch throws another exception, and that triggers the call to terminate.
When b.f() is called in main, a Fruit is thrown. Then execution leaves the try block, and before any catch handler can catch that Fruit, b is destroyed and 'c' is thrown. Throwing a second exception while the Fruit is still active leads to termination, regardless of any catch handlers.
This is the reason why you never shall throw from destructors.
because the program flow is as follows:
try{
Botch b;
b.f();
//-> exception of class Fruit has been thrown
//-> Stack unwinding: during stack unwinding object b,
//which is on stack is destroyed, and its destructor is called
//-> this destructor ~Botch() { throw 'c'; } throws another exception
//and this caused call of your terminator()
} catch(Fruit&) { // so we are never here

try/catch to avoid .stackdump

In the code below i use try/catch in the python module code. In the try block i have a simple error (memory access violation) and trying to catch the corresponding exception and to terminate the program quietly without generation of the .stackdump file. However the latter is still generated what implies that try/catch construct does not do its job. How could i avoid generating .stackdump file and exit the program without errors when the improper operation (like one in the code) is met?
P.S. i'm compiling the code in cygwin with gcc and boost.python
It is interesting that it doesn't work only in case x[3]=2, but works for all other cases: e.g. x[4]=2 or x[20]=2 or, obviously, x[2]=2.
#include <boost/python.hpp>
#include <iostream>
#include <iomanip>
using namespace std;
using namespace boost::python;
class Hello
{
std::string _msg;
public:
Hello(std::string msg){_msg = msg;}
void run(){
try{
double* x;
x = new double[3];
x[3] = 2.0;
delete [] x;
}catch(...){ exit(0); }
}
};
BOOST_PYTHON_MODULE(xyz)
{
class_<Hello>("Hello", init<std::string>())
.def("run",&Hello::run)
;
}
EDIT:
According to what Maciek has suggested i tried the following trick:
Make signal handling function to throw an exception, but not exit
void sig_action(int signo) {
std::cout << "SIGNAL " << signo << std::endl;
throw 1;
// exit(0);
}
And now try to enclose a possibly problematic function in try/catch block (signal function is placed in class constructor):
class Hello
{
std::string _msg;
public:
Hello(std::string msg){
_msg = msg;
signal(SIGABRT, sig_action);
signal(SIGSEGV, sig_action);
}
void set(std::string msg) { this->_msg = msg; }
std::string greet() { return _msg; }
void run(){
try{
double* x;
x = new double[3];
x[3] = 2.0;
delete [] x;
}catch(...){ cout<<"error in function run()\n"; exit(0); }
}
};
However such a trick doesn't work as i expected it produces the following output:
SIGNAL 6
terminate called after throwing an instance of 'int'
SIGNAL 6
terminate called recursively
SIGNAL 6
terminate called recursively
....
(and many more times the same)
So the exception is thrown, but everything finishes before it has been caught. Is there any way to let it be caught before terminating the process?
You can only catch exceptions that are thrown. An invalid pointer access doesn’t throw an exception, it simply causes undefined behaviour, and in your particular case it results in a stack dump.
If you want to catch such a situation situation, use std::vector and the at function to access items. This will throw std::out_of_range when used with an invalid index. However, it’s usually better to avoid the possibility of such accesses a priori since they are usually indicative of a bug in your program, and bugs should not be handled via exceptions, they should be removed from the code.
On linux core dumps are generated by signal handlers with default action set to core (SIGABRT, SIGSEGV, ...). If you want to avoid core dump you can always capture/ignore those signals. It should work on Cygwin stackdumps as well. But you will still probably get some nasty message as output.
EDIT:
#include <signal.h>
// [...]
void sig_action(int signo) {
std::cout << "SIGNAL " << signo << std::endl;
exit(0);
}
int main(int argc, char* argv[]) {
signal(SIGABRT, sig_action);
signal(SIGSEGV, sig_action);
Hello h("msg");
h.run();
}

Stop execution without skipping destructors

Is it possible to terminate software execution without skipping calls to destructors? For instance, in the code below, the destructor for test will never be called because of the exit(1) statement.
#include <iostream>
#include <cstdlib>
using namespace std;
class A{
public:
A(){cout << "Constructed.\n";}
~A(){cout << "Destroyed.\n";}
};
void func()
{
//Assuming something went wrong:
exit(1);
}
int main(int argc, char *argv[])
{
A test;
func();
return 0;
}
What I need, is a way to end the program (from within func()) that calls all necessary destructors before terminating. So far I've been handling this through func() return value, as in:
bool func()
{
//Assuming something went wrong:
return false;
}
int main(int argc, char *argv[])
{
A test;
if( !func() )return 1;
return 0;
}
The problem with this method is that it quickly becomes very annoying (and code bloating) to manage once you need to apply it to a series of nested functions.
Is there a way of achieving the same results of the second example (proper destructor calls) with a syntax similar to the first example (call exit(1) wherever you are)?
Throw an exception, catch it in main and return.
This relies on nothing else catching your exception without rethrowing it.
You could rely on stack unwinding for this: when you want to exit, throw an exception and catch it in main().
struct my_exit
{
int error;
int operator()()
{
// do any cleanup on globals
return error;
}
};
int main()
{
try
{
doSomethingThatCouldCauseExit();
}
catch (my_exit & me)
{
// Clean up globals now
exit(me());
}
}
There are several ways to do this cleanly.
One solution is to use the atexit function, which simply calls the given function pointer when the program terminates.
You would have to allocate all of your objects off the heap, maintain some global table with pointers to all instantiated class instances, and then simply iterate through the table delete ing each instance in the registered function.

why does throw "nothing" causes program termination?

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.