PasalicZaharije wrote:
Hallo,
few days ago I see ctor like this:
Ctor() try : v1(0) {
// some code
}
catch(...) {
// some code
}
This is something realy shocking for me. So I write something like:
class Kljasa {
int *bvarijabla;
public:
// first ctor
Kljasa(int cvarijabla) try {
bvarijabla = new int[cvarijabla];
}
catch(...) {
cout << "CTOR DOWN" << endl;
bvarijabla = NULL;
This last statement is both pointless and technically illegal. It is
pointless because the constructor is failing by an exception (and using
a function-try-block ALWAYS ends with an exception; see below), which
means that the object and its members don't exist -- i.e., the memory
allocated for bvarijabla is about to be returned to the memory pool
from which it came (usually the stack or heap) and can never be
accessed. Thus setting it to NULL does nothing for you or your user.
Accessing bvarijabla in the catch block is illegal according to the
Standard because all class members are out of scope in the catch block.
Since it apparently built for you, however, this represents a
non-conformancy or bug in your compiler.
}
//second like first with try block inside
Kljasa(int cvarijabla, int dummy) {
try {
bvarijabla = new int[cvarijabla];
}
catch(...) {
cout << "CTOR DOWN" << endl;
bvarijabla = NULL;
}
}
};
If I write:
Kljasa k(-10, 1); // second ctor
everithing is OK - exception is catched and programm continues to execute
(I know that this ctor-catching is not good solution but suppose that it's
ok).
Now, when I try to call first ctor my program
crashs with "abnormal program termination" but catch block displayed "CTOR
DOWN". It sems like
catch block rethrow exception again?!
My qusetion is: what first ctor realy do if exception is throwed?
Note, that I tested this only with MinGW 3.4.2.
Thanks,
Zaharije Pasalic
Check out this link:
http://www.gotw.ca/gotw/066.htm
It discusses the uses and limitations of function-try-blocks. And yes,
the function-catch block ALWAYS exits by throwing an exception --
either explicitly (i.e., you rethrow the exception that was caught or
throw some other exception) or implicitly (i.e. if you let control pass
to the end of catch block without throwing it implicitly rethrows the
exception that was caught). This is standard behavior for
function-try-blocks. As that link argues, the only practical use for
function-try-blocks is to translate one exception type to another.
Your second constructor could catch a failed new, but it could not
catch an exception emitted by the constructor of a base class of Kljasa
or by the constructor of a member of Kljasa:
class MyException {};
class Throws { Throws() { throw MyException(); } };
class Kljasa
: public Throws
{
Throws throws_;
public:
Kljasa()
: Throws()
, throws_()
{
try { }
catch( const MyException& e )
{
// Control will never reach here
}
}
};
Here, both the member throws_ and the base Throws (which needn't be
listed explicitly in the constructor initialization list because their
default constructors would automatically be invoked in the same way,
but which are listed for purposes of illustration) would throw but
neither exception could be caught by the constructor.
Cheers! --M