Try catch in ctor initialization list

  • Thread starter PasalicZaharije
  • Start date
P

PasalicZaharije

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;
}

//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
 
K

Karl Heinz Buchegger

PasalicZaharije said:
My qusetion is: what first ctor realy do if exception is throwed?

You need to ask the experts for your compiler, since this
is a nonstandard enhancement of your compiler.
 
M

Markus Moll

Hi
You need to ask the experts for your compiler, since this
is a nonstandard enhancement of your compiler.

I'm not sure what you mean.
However, this is simply undefined behaviour, as:

"Referring to any non-static member or base class of an object in the
handler for a function-try-block of constructor or destructor for that
object results in undefined behavior."

These objects have all been destroyed before the catch-block is entered.

Markus
 
M

mlimber

PasalicZaharije said:
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
 
M

mlimber

mlimber said:
PasalicZaharije said:
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.
[snip]

Oops. Members are not out of scope, but as Markus Moll said elsewhere
on this thread, accessing them does result in the dreaded UB --
undefined behavior.

Cheers! --M
 
M

mlimber

Karl said:
You need to ask the experts for your compiler, since this
is a nonstandard enhancement of your compiler.

The OP has the syntax for function-try-blocks wrong, but the feature
does exist in the standard.

Cheers! --M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top