class A
{
int a,b;
public:
A(int X,int Y)
{
X = a;
Y = b;
try
{
if (b == 0)
throw b;
else
cout << a / b;
}
catch (int a)
{
cout << a; //throw;can we rethrow??then what is purpose of it??
}
}
};
"can we rethrow?" - Yes. You can always rethrow a caught exception, to let someone higher up in the call-stack also handle it (or have it terminate the program if not caught).
An exception in the constructor means something really bad happened, and since constructors can't return a (invalid) value to indicate failure in proper object construction, there are 3 options: to initialize the object in some special state in a hope that somewhere else in the caller code it'll be checked and handled properly, or to set an external variable/flag to mark the initialization failure, or to throw an exception after releasing any memory that it dynamically allocated. In general, if an exception is thrown before an object is fully constructed, destructors will be called for any member objects that have been constructed so far. And if an array of objects has been partially constructed when an exception occurs, only the destructors for the array’s constructed objects will be called. In addition, destructors are called for every automatic object constructed in a try block before an exception that occurred in that block is caught.
Related
Consider the following situation:
struct X { ... };
struct Y
{
Y(...);
...
X x;
...
}
X f()
{
...
if (...)
throw E;
...
}
Y::Y(...) :
... ,
x(f()) ,
...
{
...
}
Is there any undefined behaviour here? Are there any gotchas or potential problems with such a design when E is thrown?
Update:
Y::x may not be the only member variable of Y, may not be the first member variable in the class, and may be initialized half way through the Y::Y init list.
Is there any undefined behaviour here?
No. The construction of Y is aborted.
Are there any gotchas or potential problems with such a design when E is thrown?
No Y is ever created, so there is no destructor to call. Destructors for fully constructed elements, those declared before x in the class body, will be called automatically (how would you otherwise know how far the initialization list you were when it throw). If you need to destroy anything, then you must catch the exception and destroy it yourself. You cannot absorb the exception, you can rethrow it, throw a new exception, or do nothing which will result in the exception being rethrown anyway. For your particular use case, there shouldn't be anything to destroy since the constructor body is not going to be invoked at all.
When an exception is throwing during the construction of an object, the destructors of all fully constructed subobjects are called. That is, assuming your type X throwing an exception correctly cleans up any resources it may have allocated before the exception was thrown, there is no issue.
This question is inspired by Using an object after it's destructor is called
Let's consider the following code
class B
{
public:
B() { cout << "Constructor B() " << endl; }
~B() { cout << "Destructor ~B() " << endl; }
};
class A {
public:
B ob;
A()
try
{
throw 4;
}
catch(...)
{
cout << "Catch in A()\n";
}
A(int)
{
try
{
throw 4;
}
catch(...)
{
cout << "Catch in A(int)\n";
}
}
};
int main()
{
try
{
A f;
}
catch (...)
{
cout << "Catch in main()\n\n";
}
A g(1);
}
It's output is
Constructor B()
Destructor ~B()
Catch in A()
Catch in main()
Constructor B()
Catch in A(int)
Destructor ~B()
In contrast to A(int), constructor A() has the initializer list try/catch syntax. Why that makes a difference on the order of the subobject destruction? Why the exception thrown in A() propagates to main()?
Why that makes a difference on the order of the subobject destruction?
When catch in A(int) - all subobjects are alive, and you can use them. Moreover, after catch, you can continue object construction, and "return" to user properly constructed object.
When catch in A() - all subobjects, which were constructed - are destructed. And you don't know which subobjects were constructed and which not - at least with current ISO C++ syntax.
Why the exception thrown in A() propagates to main()?
Check GotW #66:
If the handler body contained the statement "throw;" then the catch block would obviously rethrow whatever exception A::A() or B::B() had emitted. What's less obvious, but clearly stated in the standard, is that if the catch block does not throw (either rethrow the original exception, or throw something new), and control reaches the end of the catch block of a constructor or destructor, then the original exception is automatically rethrown.
Think about what this means: A constructor or destructor function-try-block's handler code MUST finish by emitting some exception. There's no other way. The language doesn't care what exception it is that gets emitted -- it can be the original one, or some other translated exception -- but an exception there must be! It is impossible to keep any exceptions thrown by base or member subobject constructors from causing some exception to leak beyond their containing constructors.
In fewer words, it means that:
If construction of any base or member subobject fails, the whole object's construction must fail.
The difference is that at the end of:
A()
try
{
throw 4;
}
catch(...)
{
cout << "Catch in A()\n";
}
the exception is implicitly rethrown and no object A get constructed, whereas in:
A(int) {
try
{
throw 4;
}
catch(...)
{
cout << "Catch in A(int)\n";
}
}
you swallow the exception and an instance of A is fully constructed.
Destructors run only on fully constructed objects, that is objects whose constructor finished successfully, without throwing an exception.
EDIT: as per the destruction of subobjcets, the catch in the first case is run after the sub-object has been destructed. This is consistent with the member initialization syntax that suggests that it is what should actually happen:
A()
try : ob() // default construct
{
throw 4;
}
catch(...)
{
// here ob is already destructed
cout << "Catch in A()\n";
}
(equivalent to the first case.)
Why that makes a difference on the order of the subobject destruction?
In general, in the function catch clause of A(), you wouldn't know which members had been successfully constructed, because the exception might have come from one of their constructors. So to remove doubt they're destroyed first. Basically the function try/catch is "outside" the data member construction.
Why the exception thrown in A() propagates to main()?
The function catch clause can't make the constructor succeed (because if its members weren't constructed successfully, then the object itself hasn't been constructed successfully). So if you don't throw something else from it then the original exception is rethrown. That's just how it's defined, you can't use a function-try clause to ignore the problem. You can use a regular try/catch inside a function to ignore a problem, then it's up to you to decide whether or not the problem has prevented the object from being correctly constructed.
I have just started using c++ boost libraries. I read in many places that when a scoped_ptr is used then the object is always destroyed even in case of exceptions.
They behave much like built-in C++ pointers except that they automatically delete the object pointed to at the appropriate time. Smart pointers are particularly useful in the face of exceptions as they ensure proper destruction of dynamically allocated objects.
I tried in the following code.
#include<boost/scoped_ptr.hpp>
class B
{
public:
B(){ std::cout<< "B constructor call\n"; }
~B(){ std::cout<<"B destructor call\n"; }
};
class A
{
public:
boost::scoped_ptr<B> b;
A():b(new B())
{
throw 1;
}
};
int main()
{
A a; return 0;
}
output:
B constructor call
terminate called after throwing an instance of 'int'
Aborted (core dumped)
There is no call to B's destructor. But I used scoped_ptr so it should have called B's destructor or did I mis-interpreted the use of scoped_ptr.
But if a surround it with try catch then B's destructor is called.
try{
A a;
} catch( ... ) {
}
In this case destructor of A will be called as all locally allocated objects in case of exception in a try block are removed from the stack and I have my pointer wrapped inside and object of scoped_ptr so when the destructor of scoped object destroys which ultimately the pointer.
So is scoped_ptr is useful because we don't have to explicitly delete the memory allocated or I mis-interpreted the description of scoped_ptr.
How can I call the destructor of class B in case of exception using scoped_ptr
There's no matching exception handler, so std::terminate is called directly, in this case without the stack being unwound. Put a try/catch in main that catches int and you'll see your destructor call, even if that handler rethrows.
C++11 §15.1/2:
When an exception is thrown, control is transferred to the nearest handler with a matching type; "nearest" means the handler for which the compound-statement or ctor-initializer following the try keyword was most recently entered by the thread of control and not yet exited.
and §15.3/9:
If no matching handler is found, the function std::terminate() is called; whether or not the stack is unwound before this call to std::terminate() is implementation-defined.
Online demo
C++ destroy a local variable when unwinding stack(return from a function, either with return keyword or with an exception), so it should see one to destroy your scoped_ptr. But in your special case, exception occurred in main so terminate will be called and kill your program before C++ unwind the stack.
void test() {throw 1;}
void main() {
string sMain;
test();
}
In above example, sMain will not destroyed because exception cause calling terminate:
sMain constructed
exception occurred: main has no where to go, and it has no handler to handle
the exception, so it will call `terminate`, but wait we are still at `main`
so we have no stack unwinding here and sMain will never destroyed!!
Why is the destructor not invoked in this code?
#include <boost/scoped_ptr.hpp>
#include <iostream>
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; throw; std::cout<<"MyClass Allocated\n"; }
~MyClass() { std::cout<<"MyClass De-allocated\n"; }
int increment() { return ++*ptr; }
};
int main()
{
boost::scoped_ptr<MyClass> myinst(new MyClass);
std::cout << myinst->increment() << '\n';
std::cout << myinst->increment() << '\n';
}
EDIT
From the answers, In understand that when an exception happens in the constructor, destructor will not be invoked. But if the exception happens in the main(), ie after the MyClass object is fully instantiated, will the MyClass destructor be invoked? If not, then why it is a smart pointer?
Adding the code
#include <boost/scoped_ptr.hpp>
#include <iostream>
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; std::cout<<"MyClass Allocated\n"; }
~MyClass() { std::cout<<"MyClass De-allocated\n"; }
int increment() { return ++*ptr; }
};
int main()
{
boost::scoped_ptr<MyClass> myinst(new MyClass);
throw 3;
std::cout << myinst->increment() << '\n';
std::cout << myinst->increment() << '\n';
}
Output:
MyClass Allocated
terminate called after throwing an instance of 'int'
Aborted
A C++ object's lifetime begins only after its constructor completes successfully.
Since the exception was thrown before constructor call was complete you don't have an complete object and hence no destructor.
Herb Sutter explains this nicely, to quote him:
Q: What does emitting an exception from a constructor mean?
A: It means that construction has failed, the object never existed, its lifetime never began. Indeed, the only way to report the failure of construction -- that is, the inability to correctly build a functioning object of the given type -- is to throw an exception. (Yes, there is a now-obsolete programming convention that said, "if you get into trouble just set a status flag to 'bad' and let the caller check it via an IsOK() function." I'll comment on that presently.)
In biological terms,
conception took place -- the constructor began -- but despite best efforts it was followed by a miscarriage -- the constructor never ran to term(ination).
Incidentally, this is why a destructor will never be called if the constructor didn't succeed -- there's nothing to destroy. "It cannot die, for it never lived." Note that this makes the phrase "an object whose constructor threw an exception" really an oxymoron. Such a thing is even less than an ex-object... it never lived, never was, never breathed its first. It is a non-object.
We might summarize the C++ constructor model as follows:
Either:
(a) The constructor returns normally by reaching its end or a return statement, and the object exists.
Or:
(b) The constructor exits by emitting an exception, and the object not only does not now exist, but never existed as an object.
EDIT 1:
But if the exception happens in the main(), ie after the MyClass object is fully instantiated, will the MyClass destructor be invoked?
Yes, it will be!
That is the purpose of using scoped_ptr, Once an exception is thrown in main, Stack Unwinding would cause all local objects to be deallocated, this means that myinst(which resides on stack) will also be deallocated, which in turn will call the destructor of MyClass.
Refer the Boost doccumentation when in doubt:
The scoped_ptr class template stores a pointer to a dynamically allocated object. (Dynamically allocated objects are allocated with the C++ new expression.) The object pointed to is guaranteed to be deleted, either on destruction of the scoped_ptr, or via an explicit reset
EDIT 2:
Why does your edited program crash?
Your program shows crashes because, You throw an exception but you never catch it. when such a scenario occurs an special function called terminate() is called whose default behavior is to call abort().It is implementation defined behavior whether stack is Unwound before terminate() is called in this particular scenarioRef 1.Seems your implementation doesn't & you should not rely on this behavior as well.
You can modify your program as follows to handle the exception and you should get the behavior you were expecting:
#include <boost/scoped_ptr.hpp>
#include <iostream>
class MyClass {
boost::scoped_ptr<int> ptr;
public:
MyClass() : ptr(new int) { *ptr = 0; std::cout<<"MyClass Allocated\n"; }
~MyClass() { std::cout<<"MyClass De-allocated\n"; }
int increment() { return ++*ptr; }
};
void doSomething()
{
boost::scoped_ptr<MyClass> myinst(new MyClass);
throw 3;
}
int main()
{
try
{
doSomething();
}
catch(int &obj)
{
std::cout<<"Exception Handled";
}
}
Ref1C++03 15.5.1 The terminate() function
In the following situations exception handling must be abandoned for less subtle error handling techniques:
....
— when the exception handling mechanism cannot find a handler for a thrown exception (15.3),
....
In such cases,
void terminate();
is called (18.6.3). In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before terminate() is called. In all other situations, the stack shall not be unwound before terminate() is called. An implementation is not permitted to finish stack unwinding prematurely based on a determination that the unwind process will eventually cause a call to terminate().
Because calling the destructor doesn't make sense in this case.
You only destruct things which are constructed, yet your object never fully constructs. Your class members have been constructed, though, and will have their destructors called.
If a constructor throws exception, then the destructor of the class will not be called, because the object is not fully constructed.
See this link how to manage resources in such situation:
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.10
When the exception is thrown from the constructor (beginning or half way or at the end of the call), then it's assured that the object is not constructed.
So it's well defined not to invoke the destructor of an object which was never constructed.
Here is one related FAQ from Bjarne's website.
The destructor for MyClass was never invoked because no objects of type MyClass were ever constructed. Each attempt to construct one was aborted, due to the exception being thrown.
As an aside, if you want your debug messages to display -- especially if you're dealing with the program crashing -- you really ought to flush the streams: i.e. using std::endl instead of '\n' at the end of line. (or inserting std::flush)
While merely using '\n' often works, there are enough situations where it fails and it's really, really confusing to debug if you don't make a habit of doing things right.
Please have a look at demo code :
class myError
{
const char* str;
public:
myError():str(NULL) {}
myError(const char* temp)
{
str = temp;
}
const char* what()
{
return str;
}
};
class ab
{
int x;
public:
ab() try :x(0)
{
throw myError("error occured in the constructor of class ab");
}
catch(myError& temp)
{
std::cout<<"Handler no. 1 of ab constructor"<<std::endl;
}
};
int main () try
{
ab bb;
cout << "Resumed execution!" << endl;
return 0;
}
catch(myError& temp)
{
std::cout<<"Handler below the main function"<<std::endl;
std::cout<<"And the error is :" <<temp.what();
}
My Questions :
Why only function try block's handler of ctor and dtor only rethows the exception? ,
and when you simply throw exception inside ctor , its handler doesn't rethrows the object? i.e
Ctor::Ctor()
{
try{
throw Excep1();
}
catch(Excep1& temp) {
std::cout<<"Doesn't rethrows the exception object";
}
}
I wanna know that how to resume the control back to cout << "Resumed execution!" << endl; , after handling rethrown object?
why is it often said that we shouldn't place function try block on dtor of base class?
The usual rule is that a catch block doesn't rethrow unless you ask it
to. How would you stop the exception from propagating otherwise. In
the case of a constructor, however, if something in the initialization
list throws, then you haven't got a fully constructed object; there is
nothing you could do with the object, not even call the destructor on
it. And if the function catch block of the constructor doesn't
rethrow, what is it going to do, since it cannot simply return (and
leave the variable on the stack)?
In all other cases, it's up do the function containing the catch block
to know what to do. In the case of your main, for example, you could
write:
try {
ab bb;
} catch (...) {
}
std::cout << "Resumed execution!" << std::endl;
What you can't do is execute code where bb would be in scope and
accessible, but not have been correctly constructed.
As for why you shouldn't place a function try block on the destructor of a
base class, I've never heard that rule. In general, destructors
shouldn't throw, so there's no point in wrapping them in a try block,
period.
For the second question, destructors shouldn't be throwing period. Consider a case where your destructor is freeing a lot of memory through delete. What would happen if your destructor threw an error before finishing the clean up? You now have a memory leak. If your destructor is causing a runtime error, then you probably have problems elsewhere in your code that you need to fix.
As usually, Herb Sutter knows and explains everything:
If the handler body contained the statement "throw;" then the catch block would obviously rethrow whatever exception A::A() or B::B() had emitted. What's less obvious, but clearly stated in the standard, is that if the catch block does not throw (either rethrow the original exception, or throw something new), and control reaches the end of the catch block of a constructor or destructor, then the original exception is automatically rethrown.
More in his article