Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

throwing exceptions from constructor and other alternatives

63 views
Skip to first unread message

alfredo...@gmail.com

unread,
Apr 30, 2006, 12:57:00 PM4/30/06
to
Hi,

I stucked on how to desing a certain class. The only part where the
algorithm can fail is at the initialization point. My question is how
to handle exceptions that can only happen at initialization. c++ throw
from constructors seem not to be optimal from the point of view of the
resulting syntax.

To give a concrete example: The class is a simple root finder, it is
usage is like this:

class function f; //defined somewhere else
double lb=1; //lower bound for function root
double ud=3; //upper bound for function root
root_finder rf(f, lb, ud); //constructor
while(root_finder.error()>0.001){
root_finder.iterate(); //iterates by bisecting the known bracket
for the root
}
cout<<"root is "<<root_finder.estimate()<<endl;

the implementation is a simple bisection algorithm, therefore it is
guarantied to converge.

The only problem that can happen is that the initial guess for lower
bound and upper bound don't bracket an odd number of roots. Once the
initial bracket encloses at least one root the "iterate()" method
doesn't have to check explicitly that the current bracket is valid. So,
in my logic, "exception only can occur during the initialization".

So trying to be elegant I added a throw exception into the root_finder
constructor: when f(lb)*f(up)>0 [i.e. both are same sign] the
constructor throws an exception

class root_finder{
root_finder(function const& f; double lb; double ub){
...
flb=f(lb); //I need to calculated this anyway for initializing
fub=f(ub); // the bracketing algorithm
if( flb*fub > 0) throw root_finder::bad_bracket; // exception.
this is the ONLY bad thing that can ever happen
...
}
}

But resulted in a bad idea because when I enclose the constructor in a
try/catch block I have to include the iterations as well. That means
that I can not do something like this;

try{
root_finder rf(f, lb, ub);
} catch(bad_bracket){
root_finder rf(f, lb-1.0, ub+1.0); //increases the bracket size;
}
while(rf.error()>0.0001){ //<- error: rf is not in this scope;
rf.iterate();
}
//the only way around is to duplicate the while block in each try/catch
block. Duplicating the while block seem to be an awful consequence of
(the elegant?) throwing exception from the constructor.

So, there are three alternatives I can think of:

1) construct a blank rf [that defers the initialization]
root_finder rf;
try{
rf=root_finder(f, lb, ub);
} catch (...){
rf=root_finder(f, lb-1.0, ub+1.0);
}
...
I don't like this solution because it requieres to define a
public default constructor root_finder() which can bring more problems

2) switch to pointer syntax
root_finder rfP=0;
try{
rfP=new root_finder(f, lb, ub);
}catch(...){
rfP=new root_finder(f, lb-1.0, ub+1.0);
}
while(rfP->error()>0.01){ rfP->iterate();}
...
I don't like this solution because it uses pointers.

3) don't use exceptions at all and give root_finder class a flag
status (like std::istream have)
root_finder rf(f, lb, ub);
if(!rf) rf=root_finder(f, lb-1.0, ub+1.0);
assert(rf);
while(rf.error()>0.01){rf.iterate();}
...
I don't like this solution because I don't like flags and that
flag is only useful just after construction. BUT it may be the best
solution anyways unless some gives me some alternative.

So,
Do you have any opinion which is the most common approach for exception
errors that can only happen at construction/initialization?
Do you have any other solutions?
Is this kind of exception forcing us to separate construction from
initialization (wathever this means) even in simple classes like this
one?

Thank you, Alfredo


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

ThosRTanner

unread,
May 1, 2006, 6:17:19 PM5/1/06
to
You could try providing a static function in the root_finder class,
something like

while (root_finder::invalid_roots(f, lb, ub))
{
lb -= 1;
ub += 1;
}

Or you could make the constructor do that work and update the boumds
itself, and then it wouldn't have to throw.

Having said which, although I'm not aware of the problem domain, it is
pretty easy to pass in a function which has no roots, and the above
loop would never terminate.

Lastly - to be honest, I can't see why you need a class to implement
this. A function that takes a function, 2 bounds and an error bound
would do what you want, without any issues.

Cheers

Tom

VSR

unread,
May 2, 2006, 6:34:53 AM5/2/06
to
>c++ throw from constructors seem not to be optimal ....

That is an understatement. Throwing from a constructor is just ugly -
the language does not prevent it, but semantically it is just 'I dont
have the right word for it'... wrong...

>most common approach for exception errors that can only happen at construction/initialization

Construction and Initialization are not necessarily the same thing. The
best approach for you is the follow the "Two phase construction"
paradigm. Where your constructor does nothing more than initializing
the member variables to default values. You should then provide an
"Initialize" method and this method is the one that will do the other
work that your ctor is currently doing.

If you dont like initialize methods just because it makes you construct
an object before hand, then make the Initialize a static method.

David Abrahams

unread,
May 2, 2006, 3:12:58 PM5/2/06
to
"VSR" <vraghu...@gmail.com> writes:

>> c++ throw from constructors seem not to be optimal ....
>
> That is an understatement. Throwing from a constructor is just ugly -
> the language does not prevent it, but semantically it is just 'I dont
> have the right word for it'... wrong...

I can't disagree more. Constructors and exceptions are a match made
in heaven. Throwing from a constructor allows you to establish strong
invariants by preventing an object from existing if the appropriate
postconditions can't be established. The alternative is weaker class
invariants, which makes reasoning about program correctness more
difficult.

>> most common approach for exception errors that can only happen at
>> construction/initialization
>
> Construction and Initialization are not necessarily the same
> thing. The best approach for you is the follow the "Two phase
> construction" paradigm. Where your constructor does nothing more
> than initializing the member variables to default values. You should
> then provide an "Initialize" method and this method is the one that
> will do the other work that your ctor is currently doing.

Two-phase construction is usually bad for robustness and simplicity:
it causes invariants to be weakened to include the state after
construction but before initialization, which means you have to
constantly check to see whether your object has been fully
initialized, and that usually complicates code.

> If you dont like initialize methods just because it makes you
> construct an object before hand, then make the Initialize a static
> method.

And how would that help?

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

James Hopkin

unread,
May 2, 2006, 3:48:07 PM5/2/06
to

alfredo...@gmail.com wrote:
> Hi,
>
> I stucked on how to desing a certain class. The only part where the
> algorithm can fail is at the initialization point. My question is how
> to handle exceptions that can only happen at initialization. c++ throw
> from constructors seem not to be optimal from the point of view of the
> resulting syntax.
>

[snip]

>
> try{
> root_finder rf(f, lb, ub);
> } catch(bad_bracket){
> root_finder rf(f, lb-1.0, ub+1.0); //increases the bracket size;
> }
> while(rf.error()>0.0001){ //<- error: rf is not in this scope;
> rf.iterate();
> }


I think giving the user the choice between error flag and exceptions
(ala iostreams) is the best way to go (assuming you need a class at all
for this task). I'd make it work something like the following:


root_finder rf(f, lb, ub, root_finder::no_exceptions_tag);
if (rf.error())
{
rf.reset(f, lb - 1, ub + 1); // if this fails, we really have a
run-time error, so throw
}

while ...


In a different use case, you may expect the bracket size to be correct,
so the immediate error checking can be skipped:


root_finder rf(f, lb, ub); // will throw if the bracket's not wide
enough
while ...


That's where you benefit from the elegance of exceptions.


James

Roy Smith

unread,
May 2, 2006, 3:55:32 PM5/2/06
to
"VSR" <vraghu...@gmail.com> wrote:
> That is an understatement. Throwing from a constructor is just ugly -
> the language does not prevent it, but semantically it is just 'I dont
> have the right word for it'... wrong...

Why? It seems to me like a perfectly reasonable thing to do. To take an
example from something I did recently, Let's say you've got a class which
represents an IP address. The constructor takes a string representation of
an address:

IPAddress addr ("127.0.0.1");

What would you expect to happen if I did

IPAddress addr ("foo");

? What I do is throw IPAddress::invalidAddressString from the constructor.
I can't imagine doing anything else that makes sense.

alfredo...@gmail.com

unread,
May 2, 2006, 4:00:46 PM5/2/06
to

> Throwing from a constructor is just ugly -
> the language does not prevent it, but semantically it is just 'I dont
> have the right word for it'... wrong...

That is what I wanted to hear. Because I suspected it.

> Construction and Initialization are not necessarily the same thing. The
> best approach for you is the follow the "Two phase construction"
> paradigm. Where your constructor does nothing more than initializing
> the member variables to default values. You should then provide an
> "Initialize" method and this method is the one that will do the other
> work that your ctor is currently doing.

Yeah, that was one of the alternatives I had in mind, the problem is
that in some classes, there are no default parameters that make any
sense: An even if you invent them arbitrarely the constructed
(uninitialized) object becomes as dangerous as a dangling pointer.
(to be more especific, root_finder has a const reference to the
function whose roots are to found, delaying initialization will force
me to convert the const reference into a -dangling- pointer to const or
check that the pointer is not null at every iteration--iterations are
a separate method--)

> If you dont like initialize methods just because it makes you construct
> an object before hand, then make the Initialize a static method.

I am interested...but I don't understand the last sentence, I though
that "initialize" methods were always static.

Thank you, Alfredo

David Abrahams

unread,
May 2, 2006, 5:57:39 PM5/2/06
to
"alfredo...@gmail.com" <alfredo...@gmail.com> writes:

>> Throwing from a constructor is just ugly -
>> the language does not prevent it, but semantically it is just 'I dont
>> have the right word for it'... wrong...
>
> That is what I wanted to hear. Because I suspected it.

On the other hand, if you are happy when you hear what you suspected,
it's hard to learn very much :)

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

alfredo...@gmail.com

unread,
May 2, 2006, 5:58:00 PM5/2/06
to

ThosRTanner wrote:
> You could try providing a static function in the root_finder class,
> something like

in general the root_finder has no good way to guess another set of
brackets. so I didn't want to include that in the root_finder class and
left this task to the user (after I find a good way to "catch" this
error).

> Having said which, although I'm not aware of the problem domain, it is
> pretty easy to pass in a function which has no roots, and the above
> loop would never terminate.

For a bracketing method the algorithms are guarantied to converge if
the initial braket are know to bracket an odd numer of roots, i.e.
f(x0)<0 and f(x1)>0 or biseversa.
So the only failure can happens at the initialization, and that is way
I though that throwing from the constructor was the way to go.

>
> Lastly - to be honest, I can't see why you need a class to implement
> this. A function that takes a function, 2 bounds and an error bound
> would do what you want, without any issues.

yeah, I could have a normal standalone function that do this, but I
never liked this approaches because you have to build-in a criterion
for convergence in the standalone function and that makes the function
as inflexible as it can be. For example, for some people convergece
means |x_n-x_{n-1}|<epsilon1, for other people convergence will mean
|f(x_n)|<epsilon2 or some other may choose
|(x_n-x_{n-1})/x_n|<epsilon3, the criteria are infinite.
I wanted the user of the class to decide when to terminate the
iterations instead. The user may want to use the intermediate results
of the interations to have an estimate for something else, i.e. before
the convergence to the actual root.

NB: I though that an approach similar to the stl containter/iterator
decoupling was a good idea in this kind of iterative algorithms; at the
end the numbers that come from the iterations may look the same way
that comming from a stl unidirectional linked list :)

Thanks, Alfredo

Francis Glassborow

unread,
May 2, 2006, 5:56:34 PM5/2/06
to
In article <1146589875.2...@u72g2000cwu.googlegroups.com>,
"alfredo...@gmail.com" <alfredo...@gmail.com> writes

>
>> Throwing from a constructor is just ugly -
>> the language does not prevent it, but semantically it is just 'I dont
>> have the right word for it'... wrong...
>
>That is what I wanted to hear. Because I suspected it.

That may be what you wanted to hear but I do not know of any experienced
user of C++ who would say that. Throwing from a constructor is an
essential technique. Two stage construction just does not work when you
include serious use of inheritance, and even less when you use
templates.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

alfredo...@gmail.com

unread,
May 3, 2006, 5:36:02 AM5/3/06
to
> >> Throwing from a constructor is just ugly -
> >> the language does not prevent it, but semantically it is just 'I dont
> >> have the right word for it'... wrong...
> >
> >That is what I wanted to hear. Because I suspected it.
>
> That may be what you wanted to hear but I do not know of any experienced
> user of C++ who would say that. Throwing from a constructor is an
> essential technique. Two stage construction just does not work when you
> include serious use of inheritance, and even less when you use
> templates.

I don't know, I have mixed fillings now. Many people is saying that
throwing from constructor is totally normal, however how do you think
the resulting syntax will look like?

try{
object construtor
use of object
}catch(...){
object construtor with alternative values
SAME use of object
}

...Well, maybe it is the way to go.

an object with a status flag (ala std::stream) may not be worst or
better alternative.

Thanks for the answers, Alfredo

alfredo...@gmail.com

unread,
May 3, 2006, 5:41:15 AM5/3/06
to
David,

Thank you for your two postings. Regarding the last one, I raised the
question because I suspected that throwing from constructor was somehow
wrong and somebody said the same, so I smiled and was happy to see that
my hypothesis was shared with someone else.

I can learn being unhappy with someone else's answer. But don't worry
for me, I will be happy again when I find the right way to continue. :)

At this point of the discussion, and having read all the answers IMHO I
think it will be a matter of taste whether to throw exception or
flag-and-reset the object. IMHO Flags-and-Resets are not so bad after
all (and I rather prefer to use a flag than to make a non-sensical
default constructor).

IMHO The two solutions seem to be equaly good (... and resulting syntax
ugly, but the very event of an exception is ugly in the first place and
so is the code to prevent it :) ).

Alfredo

David Abrahams wrote:
> "alfredo...@gmail.com" <alfredo...@gmail.com> writes:
>
> >> Throwing from a constructor is just ugly -
> >> the language does not prevent it, but semantically it is just 'I dont
> >> have the right word for it'... wrong...
> >
> > That is what I wanted to hear. Because I suspected it.
>
> On the other hand, if you are happy when you hear what you suspected,
> it's hard to learn very much :)

Nicola Musatti

unread,
May 3, 2006, 4:00:45 PM5/3/06
to

alfredo...@gmail.com wrote:
[...]

> I don't know, I have mixed fillings now. Many people is saying that
> throwing from constructor is totally normal, however how do you think
> the resulting syntax will look like?
>
> try{
> object construtor
> use of object
> }catch(...){
> object construtor with alternative values
> SAME use of object
> }
>
> ...Well, maybe it is the way to go.
>
> an object with a status flag (ala std::stream) may not be worst or
> better alternative.

I think your problem is with the overall design. Construction should be
a self contained, all-or-nothing process. Instead your example clearly
indicates an iterative process where feedback from outside the object
is needed to converge on stable initial conditions.
But, wait, if you need to converge, those conditions aren't initial in
any sense of the word!

At the very least you should separate bracket finding from root
finding, than pass the valid bracket to the root_finder constructor and
enforce the validity of the bracket with an assertion.

Cheers,
Nicola Musatti

Eberhard Schefold

unread,
May 3, 2006, 4:07:46 PM5/3/06
to
alfredo...@gmail.com wrote:

> try{
> object construtor
> use of object
> }catch(...){
> object construtor with alternative values
> SAME use of object
> }

Is that really your situation? You try to create an object with argument
a1, and if that fails, it makes sense to try again with a specific
different argument a2? There is no way to tell in advance which argument
will lead to success?

I have a strong feeling that this situation can be re-designed in a
better way.

James Hopkin

unread,
May 3, 2006, 4:10:37 PM5/3/06
to
>
> I don't know, I have mixed fillings now. Many people is saying that
> throwing from constructor is totally normal, however how do you think
> the resulting syntax will look like?
>
> try{
> object construtor
> use of object
> }catch(...){
> object construtor with alternative values
> SAME use of object
> }
>

If you go with the throwing constructor, I would suggest the following:

#include <boost/optional.hpp>

boost::optional<root_finder> opt_finder;
try
{
opt_finder = root_finder(f, lb, ub);
}
catch (root_finder::bracket_too_narrow&)
{
opt_finder = root_finder(f, lb - 1.f, ub + 1.f); // will throw if
still not wide enough
}

// use opt_finder

Note particularly that the try block is as small as possible and the
catch block only catches the exception we're expecting.

(Side-note: even if root_finder is not copyable for some reason,
boost::optional provides a factory creation mechanism to cope with
that)

Particularly in C++, exceptions aren't pretty when they're used to deal
with expected conditions as above.

Another idea would be for root_finder to provide a static function that
evaluates whether a set of parameters is valid:

if (!root_finder::parameters_valid(f, lb, ub))
{
lb -= 1.f;
ub += 1.f;
}

root_finder rf(f, lb, ub); // will throw if bracket still not wide
enough
// use rf

The constructor could call parameters_valid internally.


James

Andrei Alexandrescu (See Website For Email)

unread,
May 4, 2006, 5:45:41 AM5/4/06
to
alfredo...@gmail.com wrote:
> At this point of the discussion, and having read all the answers IMHO I
> think it will be a matter of taste whether to throw exception or
> flag-and-reset the object.

I think this conclusion illustrates a weakness of newsgroups in general.
Fairly strong arguments have been made in favor of throwing exceptions
from constructors. Aside from that, yes, people might prefer to use
other means, but they cannot support their viewpoint as strongly. In
that sense, yes, it is a matter of preference - a strong one :o).

> IMHO Flags-and-Resets are not so bad after
> all (and I rather prefer to use a flag than to make a non-sensical
> default constructor).

Flags and Resets have their value. If your default constructor can't put
an object in a meaningful state, and if you want to create arrays,
there's no other way.

> IMHO The two solutions seem to be equaly good (... and resulting syntax
> ugly, but the very event of an exception is ugly in the first place and
> so is the code to prevent it :) ).

It's hard to argue against "ugly" as it conveys a feeling rather than an
idea.


Andrei

David Abrahams

unread,
May 4, 2006, 5:57:26 AM5/4/06
to
"alfredo...@gmail.com" <alfredo...@gmail.com> writes:

> the very event of an exception is ugly in the first place

That is an attitude I've had some success in changing. While it's
clearly a valid point-of-view, it doesn't tend to lead to a powerful
relationship with error handling.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Greg Herlihy

unread,
May 4, 2006, 5:58:33 AM5/4/06
to
alfredo...@gmail.com wrote:
> > >> Throwing from a constructor is just ugly -
> > >> the language does not prevent it, but semantically it is just 'I dont
> > >> have the right word for it'... wrong...
> > >
> > >That is what I wanted to hear. Because I suspected it.
> >
> > That may be what you wanted to hear but I do not know of any experienced
> > user of C++ who would say that. Throwing from a constructor is an
> > essential technique. Two stage construction just does not work when you
> > include serious use of inheritance, and even less when you use
> > templates.
>
> I don't know, I have mixed fillings now. Many people is saying that
> throwing from constructor is totally normal, however how do you think
> the resulting syntax will look like?
>
> try{
> object construtor
> use of object
> }catch(...){
> object construtor with alternative values
> SAME use of object
> }
>
> ...Well, maybe it is the way to go.
>
> an object with a status flag (ala std::stream) may not be worst or
> better alternative.

The problem here is not throwing an exception from a constructor - the
problem is that an object is being constructed at all. Finding the root
of a number does not describe a class object - it describes a process
that applies an algorithm to input data in order to produce a result.
And as an algorithm, finding the root is most sensibly implemented as a
function - not as some kind of object.

It is easy to get carried away with object-oriented design and try to
create objects for everything - but the object-oriented approach is not
the best choice for every task. There are many reasons (aside from the
constructor issue) why a "root finder" object is not well-suited for
the task of finding roots. For example, consider destruction. An
algorithm eventually reaches a conclusion - the root is found - and the
process terminates itself by returning with its result. An object in
constrast does not reach any sort of self-directed "conclusion" -
rather an object is typically deleted by an owning agent for as part of
a larger process (or object) of which the object is only a part. In
other words, what is the value in keeping a root finder object around
after the root has been found?

Implementing root finding as a function would also resolve the issue
with exceptions. Since the inputs are guesses in the first place, and
the corrective action for unsuitable values is already known - a
function would not throw an exception back to the caller when passed
unsuitable values. The function could simply adjust the guesses passed
by the client, and thereby encapsulate the entire root-finding process
into a single routine that clients can invoke without having first to
take precautionary measures.

Greg

Alf P. Steinbach

unread,
May 4, 2006, 5:54:57 AM5/4/06
to
* alfredo...@gmail.com:

> ThosRTanner wrote:
>> You could try providing a static function in the root_finder class,
>> something like
>
> in general the root_finder has no good way to guess another set of
> brackets. so I didn't want to include that in the root_finder class and
> left this task to the user (after I find a good way to "catch" this
> error).

The root finder class doesn't need to guess, it only needs to provide
the static function.

Or a free-standing function.

Then there is no problem; the apparent problem only stems from the
insistence on having the root finder do what you say there is no good
way for it to do.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

David Abrahams

unread,
May 4, 2006, 5:56:44 AM5/4/06
to
"alfredo...@gmail.com" <alfredo...@gmail.com> writes:

> I don't know, I have mixed fillings now. Many people is saying that
> throwing from constructor is totally normal, however how do you
> think the resulting syntax will look like?
>
> try{
> object construtor
> use of object
> }catch(...){
> object construtor with alternative values
> SAME use of object
> }

It is not normal to use try/catch immediately around everything that
throws. It's usually a sign of misdesign. If the pattern above was
the normal result of throwing from a particular ctor, I'd redesign the
ctor so that it could try one method, then try the other method,
internally, and only throw if all construction methods failed.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

john...@yahoo.com

unread,
May 4, 2006, 5:52:43 AM5/4/06
to
alfredo...@gmail.com wrote:

> I don't know, I have mixed fillings now. Many people is saying that
> throwing from constructor is totally normal, however how do you think
> the resulting syntax will look like?
>
> try{
> object construtor
> use of object
> }catch(...){
> object construtor with alternative values
> SAME use of object
> }
>

The problem really isn't about throwing from a constructor. As others
have said, throwing from constructors is actually a good thing, because
it lets you write classes which guarantee strong invariants.

The real problem is that exceptions don't mix well with the
retry-and-resume style of error handling. (Exceptions are better
suited to the clean-up-and-fail style.) That's one reason to avoid
using exceptions to signal a "recoverable" error. However, with
constructors, exceptions are really the only way to signal failure
(unless you get into the whole status flag mess, which we want to
avoid.)

So it's often a good idea to avoid designing constructors that have
"re-tryable" failure modes -- perhaps by including the recovery / retry
code in the constructor itself.

But since that's not always possible or desirable, you may need to
adapt a throwing constructor to a retry-and-resume style. You can do
this by wrapping the initialization of the object in a function. In
the following example, the function make_foo() retries the construction
of a foo object until it succeeds.

#include <iostream>

struct foo {
struct bad_i {};
foo( int i ): data(i)
{
if (i < 0) throw bad_i();
}
foo( const foo& rhs ): data( rhs.data )
{
std::cout << "copied!\n";
}
int data;
};

// helper function - wraps the retry loop
foo make_foo( int i )
{
while ( true ) {
try {
return foo(i);
}
catch( const foo::bad_i& ) {
++i; // fix up parameter
}
}
}

int main()
{
foo f1 = make_foo( -3 );
foo f2 = make_foo( -1 );
std::cout << f1.data << ' ' << f2.data << std::endl;
}

The foo copy constructor produces output, so you can tell whether your
compiler applies the RVO to eliminate copying the function return
value. On my compiler, g++ 3.4.2, no copy is made. In effect, we're
using the RVO to "teleport" an object from one scope (inside the try
block inside the function) to another (the scope of main()).

alfredo...@gmail.com

unread,
May 4, 2006, 4:40:36 PM5/4/06
to
Hi James,

Thank you for your knowlegeable answer (I was not aware of this
optional library) and definitelly solves the original question in the
sense that removes repeated code in case the user of the class wants to
use the exception mechanism to try with other new values. Ultimatelly
is like adding a flag to root_finder but this is more elegant and the
writer of the class can concetrate only in throwing and not in flag
conventions.

Just for curiosity: How would you use a method of opt_finder? like
normally opt_finder.iterate() e.g. right?


> Another idea would be for root_finder to provide a static function
> that
> evaluates whether a set of parameters is valid:
>
> if (!root_finder::parameters_valid(f, lb, ub))
> {
> lb -= 1.f;
> ub += 1.f;
> }
>
> root_finder rf(f, lb, ub); // will throw if bracket still not wide
> enough
> // use rf

the problem I see with this is that the function will be evaluated at
least twice at each point, even in a favorable guess. The logic of my
original question was "why check before construction if construction is
somehow checking for the validity of the arguments?".

You finished convincing me that throwing from constructor is not wrong,
because even in the worst case it is just a better assert and in the
best case it can be used wisely by the user of the class. And that it
is all about how to design the client code, for example the class
doesn't have to know about the existence of boost::optional or the
validation routines and can be self contained.

Alfredo

alfredo...@gmail.com

unread,
May 4, 2006, 4:44:33 PM5/4/06
to
> Is that really your situation? You try to create an object with
> argument
> a1, and if that fails, it makes sense to try again with a specific
> different argument a2? There is no way to tell in advance which
> argument
> will lead to success?

It was just an example, but Yes, I wanted to make obvious that the only
one that has any hope to try with new parameters is the user of the
function and not the class, because in general the user knows more
about the problem.

>
> I have a strong feeling that this situation can be re-designed in a
> better way.

Yes, I think at the end it is a problem of the design of the client
code.
My last conclusion is that there is nothing wrong with throwing from
constructor but the way I catch it.

Francis Glassborow

unread,
May 4, 2006, 4:55:56 PM5/4/06
to
In article <1146621788.2...@y43g2000cwc.googlegroups.com>,
"alfredo...@gmail.com" <alfredo...@gmail.com> writes

>>>> Throwing from a constructor is just ugly -
>>>> the language does not prevent it, but semantically it is just 'I
>>>> dont
>>>> have the right word for it'... wrong...
>>>
>>> That is what I wanted to hear. Because I suspected it.
>>
>> That may be what you wanted to hear but I do not know of any
>> experienced
>> user of C++ who would say that. Throwing from a constructor is an
>> essential technique. Two stage construction just does not work
>> when you
>> include serious use of inheritance, and even less when you use
>> templates.
>
> I don't know, I have mixed fillings now. Many people is saying that
> throwing from constructor is totally normal, however how do you think
> the resulting syntax will look like?

You are confusing design issues with language ones.


>
> try{
> object construtor
> use of object
> }catch(...){
> object construtor with alternative values
> SAME use of object
> }

This code makes no sense from the design perspective. And it would rely
on an (ab)use of exceptions. If the construction fails it is because the
arguments provided somehow failed to meet the requirements of the type.
Typical example would be a case where an argument designated a file that
did not exist.

If there is an alternative action that can create a complete instance of
the type then the constructor should do it. An exception should indicate
a serious problem not just a switch to an alternative.

>
> ...Well, maybe it is the way to go.
>
> an object with a status flag (ala std::stream) may not be worst or
> better alternative.
>

There are many ways to design classes that handle failures. The sad
thing is that so many programmers assume that one size fits all.

One option is to have some kind of default object that will report that
it is not a 'normal' object by the way it behaves. iostream objects are
a bit like this and their default behaviour of do nothing, do not touch
the data etc. is a frequent cause of problems to newcomers who are
puzzled by why their programs are not working the way they expect.
However the justification for this is that 'broken' iostream objects are
generally reparable and the action of do nothing prevents further damage
in the meantime.

Please try to understand what exceptions are for and the other design
options available to you and then design your class for its
requirements. Two stage construction is nearly always a mistake. When
construction completes the object should be in a stable and usable
state, if achieving that requires the separate call of an init()
function your design is probably flawed.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/
youcandoit/projects

James Hopkin

unread,
May 8, 2006, 8:41:56 AM5/8/06
to

alfredo...@gmail.com wrote:
>
> Just for curiosity: How would you use a method of opt_finder? like
> normally opt_finder.iterate() e.g. right?
>

You use opt_finder as if it were a pointer:

opt_finder->iterator()

See www.boost.org/libs/optional/doc/optional.html for more details


James

VSR

unread,
May 8, 2006, 3:30:14 PM5/8/06
to
David,

I was away for a while so apologize for a delayed response.

I do not understand how you so vehemantly seem to support throwing from
constructors.

what happens if your constructor throws "after" it had allocated some
heap memory for some of its member variables?

a constructor that throws never lets the object to be created - no
object created = no destructor invoked.

There are more elegant ways to design classes than just throwing from
ctors -

throwing from ctor may be OK for really simple classes that are just
placeholders - like the IP class someone was talking about.

Just for your reference, here is a nice discussion about this topic by
one of the industry experts in C++ -

http://www.gotw.ca/publications/mill13.htm

-Vinayak
-Vinayak

Bob Bell

unread,
May 8, 2006, 3:51:45 PM5/8/06
to
Greg Herlihy wrote:
> Implementing root finding as a function would also resolve the issue
> with exceptions. Since the inputs are guesses in the first place, and
> the corrective action for unsuitable values is already known - a
> function would not throw an exception back to the caller when passed
> unsuitable values. The function could simply adjust the guesses passed
> by the client, and thereby encapsulate the entire root-finding process
> into a single routine that clients can invoke without having first to
> take precautionary measures.

Of course, the preceding paragraph applies just as well to a
constructor for a root_finder class; there's no reason why the
constructor couldn't also adjust guesses and continue.

But otherwise I agree with your points -- there doesn't seem to be any
reason to make root_finder a class in the first place.

Bob

john...@yahoo.com

unread,
May 9, 2006, 8:17:56 AM5/9/06
to
VSR wrote:

> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

Ideally, each base class sub-object and member should be written to
clean up after itself (i.e. to practice RAII).

> a constructor that throws never lets the object to be created - no
> object created = no destructor invoked.

Yes and no. If a base class's ctor has completed, its dtor will run.
If a member object's ctor has completed, its dtor will run. It is only
the dtor for the throwing class itself which doesn't run.

> Just for your reference, here is a nice discussion about this topic by
> one of the industry experts in C++ -
>
> http://www.gotw.ca/publications/mill13.htm
>

In that article, Herb Sutter wrote: "I've always had a love/hate
relationship with exceptions, and have sometimes taken a dim view of
them. Even so, I've always had to agree that exceptions are the right
way to signal constructor failures given that constructors cannot
report errors via return codes (ditto for most operators). I have found
the 'if a constructor encounters an error, set a status bit and let the
user call IsOK() to see if construction actually worked' method to be
outdated, dangerous, tedious, and in no way better than throwing an
exception."

Are you agreeing with this view?

Jerry Coffin

unread,
May 9, 2006, 8:20:30 AM5/9/06
to
In article <1147013121.910147.167260
@j73g2000cwa.googlegroups.com>, vraghu...@gmail.com
says...

[ ... ]

> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

A class should have one responsibility -- and remote
ownership is enough responsibility for one class. That
means you only have one pointer in a particular class,
and that allocation either succeeds or fails. If it
succeeds, the object exists and life is good. If it
fails, there's nothing else to do -- the object was never
constructed.

If you have a class that needs to own more than one thing
remotely, it should do so by including a number of other
objects, each of which itself handles allocating and
freeing memory in its ctor and dtor respectively. At that
point, the object has a number of sub-objects -- and if
one of them throws, then all the previously-constructed
sub-objects will be destroyed automatically (and, of
course, the failing allocation and any other sub-objects
will never be allocated in the first place).

> a constructor that throws never lets the object to be created - no
> object created = no destructor invoked.

Sort of -- its OWN dtor won't be invoked, but if it
contains sub-objects that have been constructed, their
dtors will be invoked.

> There are more elegant ways to design classes than just throwing from
> ctors -

I can't imagine a (useful) class that just throws from
its ctor, but if an attempt at creating an object fails,
then by far the most elegant thing for it to do is throw
an exception -- in fact, the ONLY choice that's anything
short of ugly and crufty is for it to throw an exception.

[ ... ]

> Just for your reference, here is a nice discussion about this topic by
> one of the industry experts in C++ -
>
> http://www.gotw.ca/publications/mill13.htm

I'd suggest you read it again. Pay particular attention
to this part:

-----------Quote from Herb---------------
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.

There are no other possibilities.
------------end of quote------------------

Modulo the grammatical slip in last sentence (it should
really read "There is no other possibility.") he's
absolutely correct -- your only choices are for the ctor
to successfully run to completion, or for it to throw an
exception. Anytime a ctor cannot complete successfully,
it MUST throw an exception.

At one time, before the language contained exception
handling, we had crufty hacks like signaling failure via
a flag -- but this truly is a crufty hack. In particular,
it's impossible to test the flag under all the
appropriate conditions, such as when a temporary object
is created in the course of evaluating an expression.

--
Later,
Jerry.

The universe is a figment of its own imagination.

David Abrahams

unread,
May 9, 2006, 8:34:34 AM5/9/06
to
"VSR" <vraghu...@gmail.com> writes:

> David,
>
> I was away for a while so apologize for a delayed response.
>
> I do not understand how you so vehemantly seem to support throwing
> from constructors.

How can I help you understand?

> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

You arrange to clean it up, by giving responsibility for each
allocated resource to a separate, named, resource manager object.

> a constructor that throws never lets the object to be created - no
> object created = no destructor invoked.

The fully-constructed members and bases get destroyed, but not the
class being constructed. That's perfect.

> There are more elegant ways to design classes than just throwing
> from ctors -

That claim is pure opinion, although taken on it's face, I agree. If
my recipe for class design amounted to "throw from all your
constructors" I wouldn't be able to write functioning programs, much
less elegant ones.

> throwing from ctor may be OK for really simple classes that are just
> placeholders - like the IP class someone was talking about.

Yes, it may be. It may also be OK for really complicated classes.

> Just for your reference, here is a nice discussion about this topic by
> one of the industry experts in C++ -
>
> http://www.gotw.ca/publications/mill13.htm

Hmm, thanks for the reference. Have you read Herb's book,
"Exceptional C++?" I think you'd find the chapter on "Writing
Exception-Safe Code" illuminating.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Bob Bell

unread,
May 9, 2006, 3:56:38 PM5/9/06
to
VSR wrote:
> David,
>
> I was away for a while so apologize for a delayed response.
>
> I do not understand how you so vehemantly seem to support throwing from
> constructors.
>
> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

Either you 1) catch, delete and rethrow, or 2) manage the heap memory
with a smart pointer member variables that will delete the memory for
you. I prefer 2 myself.

> a constructor that throws never lets the object to be created - no
> object created = no destructor invoked.

If the constructor for some class C throws, the C destructor is not
called, but the destructors of all its members and bases *are* called.

> There are more elegant ways to design classes than just throwing from
> ctors -

Maybe you could outline them, because I'm unaware of a more elegant
strategy than preventing an object from existing when its invariants
can't be established.

> throwing from ctor may be OK for really simple classes that are just
> placeholders - like the IP class someone was talking about.
>
> Just for your reference, here is a nice discussion about this topic by
> one of the industry experts in C++ -
>
> http://www.gotw.ca/publications/mill13.htm

This article doesn't seem to support in any way the notion that
constructors shouldn't throw, and in fact I've read many other articles
by Herb where he explicitly says throwing from constructors is a good
idea.

Bob

Påhl Melin

unread,
May 9, 2006, 4:08:56 PM5/9/06
to
VSR wrote:
> David,
>
> I was away for a while so apologize for a delayed response.
>
> I do not understand how you so vehemantly seem to support throwing from
> constructors.
>
> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

The constructor must, of course, free the allocated memory (and all
other allocated resources) before if throws. Anything less is a pure
bug.

> a constructor that throws never lets the object to be created - no
> object created = no destructor invoked.

Yes, that's precisely how it should be. But remember, all destructors
of base objects and member objects created so far are called. And
what's the problem with cleaning up in the constructor (maybe calling a
helper function from both the contructor - before it thows - and
the destructor)? The only problem I can imagine is if you allocate
unmanged memory in the initializer list in the constructor. Just don't
do that. Put all unmanaged memeory allocation in the contructor body.
Or even better, use RAII objects in the class for all allocated
resources and they will be cleaned up automatically when throwing.

> There are more elegant ways to design classes than just throwing from
> ctors -
>
> throwing from ctor may be OK for really simple classes that are just
> placeholders - like the IP class someone was talking about.
>
> Just for your reference, here is a nice discussion about this topic by
> one of the industry experts in C++ -
>
> http://www.gotw.ca/publications/mill13.htm

Have you actually read the article (or the More Exceptional C++ book
where it also appears)? Herb Sutter doesn't discuss if you should throw
from constructors or not. He discusses if you should use function try
blocks or not. A very rare C++ construct that I haven't seen in any
real code or used myself:

> // Example 1
> //
> class C : private A
> {
> // ...
>
> B b_;
> };
>
> In the C constructor, say you want to catch an exception thrown from
> the constructor of a base subobject (such as A) or a member object
> (such as b_). That's what function try blocks are for:
>
> // Example 1(a): Constructor function try block
> //
> C::C()
> try
> : A ( /*...*/ ) // optional initialization list
> , b_( /*...*/ )
> {
> }
> catch( ... )
> {
> // We get here if either A::A() or B::B() throws.
>
> // If A::A() succeeds and then B::B() throws, the
> // language guarantees that A::~A() will be called
> // to destroy the already-created A base subobject
> // before control reaches this catch block.
> }

Herb Sutter does however comment on throwing from constructors in the
article:


> I've always had a love/hate relationship with exceptions, and have sometimes taken
> a dim view of them. Even so, I've always had to agree that exceptions are the right
> way to signal constructor failures given that constructors cannot report errors via
> return codes (ditto for most operators). I have found the "if a constructor encounters
> an error, set a status bit and let the user call IsOK() to see if construction actually
> worked" method to be outdated, dangerous, tedious, and in no way better than
> throwing an exception.

Thus, Herb view is that exceptions is the right way to signal
contructor failure and using two phase construction with status code
functions are "outdated, dangerous and tedious".

/ Påhl

samy....@gmail.com

unread,
May 9, 2006, 4:07:50 PM5/9/06
to
>From VSR :

> I do not understand how you so vehemantly seem to support throwing from
> constructors.
>
> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

Pure and simple :

// in constructor :
dumb_pointer = NULL;
...
try
{
dumb_pointer = new T:
...
throw Something;
}
catch(...)
{
delete dumb_pointer;
throw;
}
...

But using smart pointers is better (RAII...).

Gerhard Menzl

unread,
May 9, 2006, 4:00:21 PM5/9/06
to
VSR wrote:

> I do not understand how you so vehemantly seem to support throwing
> from constructors.

Perhaps that is because you have not followed the emerging views on
exceptions within the C++ community during the past ten years close
enough? Throwing from constructors is a standard idiom.

> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

std::auto_ptr or whatever RAII mechanism you have used to make the
constructor exception-safe will clean it up.

> a constructor that throws never lets the object to be created - no
> object created = no destructor invoked.

Which is precisely the point: an object either comes alive with all its
invariants intact, or it never comes into existence.

> There are more elegant ways to design classes than just throwing from
> ctors -

Like?

> throwing from ctor may be OK for really simple classes that are just
> placeholders - like the IP class someone was talking about.

In general, the more complicated a class is, the more likely it is that
its constructor may throw.

> Just for your reference, here is a nice discussion about this topic by
> one of the industry experts in C++ -
>
> http://www.gotw.ca/publications/mill13.htm

The industry expert you are referring to is indeed an authority on
exception-safe programming and would be very surprised to be quoted in
support of a view like yours. Have you read the entire article? It
points out what you are arguing against, i.e. that failure-proof
constructors are generally not feasible. I recommend making yourself
familiar with Herb's other articles on exception safety, especially on
his books "Exceptional C++" and "More Exceptional C++".

--
Gerhard Menzl

#dogma int main ()

Humans may reply by replacing the thermal post part of my e-mail address
with "kapsch" and the top level domain part with "net".

The information contained in this e-mail message is privileged and
confidential and is for the exclusive use of the addressee. The person
who receives this message and who is not the addressee, one of his
employees or an agent entitled to hand it over to the addressee, is
informed that he may not use, disclose or reproduce the contents thereof.

Francis Glassborow

unread,
May 9, 2006, 7:19:39 PM5/9/06
to
In article <1147013121.9...@j73g2000cwa.googlegroups.com>, VSR
<vraghu...@gmail.com> writes

>David,
>
>I was away for a while so apologize for a delayed response.
>
>I do not understand how you so vehemantly seem to support throwing from
>constructors.

Because the alternative is what is called two stage construction which
requires far too much manual maintenance and works very badly in the
contexts of templates and inheritance.


>
>what happens if your constructor throws "after" it had allocated some
>heap memory for some of its member variables?

There are perfectly good idioms for dealing with that problem (dynamic
resources should be handled by things like smart pointers etc.)

>
>a constructor that throws never lets the object to be created - no
>object created = no destructor invoked.

Well yes, but the destructors for all the completed bases and members
WILL be called so all that you need to do is to ensure that a
dynamically allocated resource is done using the RAII idiom.

>
>There are more elegant ways to design classes than just throwing from
>ctors -

Sometimes, but as a general rule, no. Classes should be designed
intelligently, however unless there is some special reason to do
otherwise, handle construction failure by throwing an exception.

On exit from a constructor all the class invariants should have been
established.


>
>throwing from ctor may be OK for really simple classes that are just
>placeholders - like the IP class someone was talking about.

Really simple classes do not need to throw from their ctors, it is all
the rest where it usually makes more sense to throw than to try to do
anything else.

If you want to see why the alternatives are often a poor solution, note
that because the default mechanism for streams is to set status flags
for failures we always have to check a streams status. We can live with
that for a stream because they may fail after construction as a result
of the data being input or output. That is the special circumstance that
justifies the use of status flags that are set during construction.

>
>Just for your reference, here is a nice discussion about this topic by
>one of the industry experts in C++ -
>
>http://www.gotw.ca/publications/mill13.htm

Indeed but did you understand what Herb was dealing with.

It is the constructor's task to create an object that conforms to the
class invariants. If you cannot do that then the constructor should fail
(and throw an exception)


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

ThosRTanner

unread,
May 9, 2006, 7:22:34 PM5/9/06
to

VSR wrote:
> David,
>
> I was away for a while so apologize for a delayed response.
>
> I do not understand how you so vehemantly seem to support throwing from
> constructors.
Because it's the only safe way to indicate an error happened in the
constructor (see the article you referenced)

>
> what happens if your constructor throws "after" it had allocated some
> heap memory for some of its member variables?

Perhaps you could try writing your constructor in an exception safe
manner? Use auto_ptr if you must initialise pointers in the initialiser
list.

>
> a constructor that throws never lets the object to be created - no
> object created = no destructor invoked.

This is an issue?

> There are more elegant ways to design classes than just throwing from
> ctors -

That is a pretty meaningless statement.

> throwing from ctor may be OK for really simple classes that are just
> placeholders - like the IP class someone was talking about.

It's OK for pretty complex classes too - I know, I've done some

> Just for your reference, here is a nice discussion about this topic by
> one of the industry experts in C++ -
>
> http://www.gotw.ca/publications/mill13.htm
>

Did you post the correct article reference. If so, did you actually
read it? That seems to me to be mainly about whether or not you should
use function try blocks. And indeed it contains this paragraph:

I've always had a love/hate relationship with exceptions, and have
sometimes taken a dim view of them. Even so, I've always had to agree
that exceptions are the right way to signal constructor failures given
that constructors cannot report errors via return codes (ditto for most
operators). I have found the "if a constructor encounters an error, set
a status bit and let the user call IsOK() to see if construction
actually worked" method to be outdated, dangerous, tedious, and in no
way better than throwing an exception.

Seems to me that Mr Sutter is pretty pro throwing exceptions as a
method of indicating an error has occured in a constructor.

w...@seed.net.tw

unread,
May 10, 2006, 8:33:09 AM5/10/06
to
john...@yahoo.com wrote:
>..

>The problem really isn't about throwing from a constructor. As others
>have said, throwing from constructors is actually a good thing, because
>it lets you write classes which guarantee strong invariants.
>
>The real problem is that exceptions don't mix well with the
>retry-and-resume style of error handling. (Exceptions are better
>suited to the clean-up-and-fail style.) That's one reason to avoid
>using exceptions to signal a "recoverable" error. However, with
>constructors, exceptions are really the only way to signal failure
>(unless you get into the whole status flag mess, which we want to
>avoid.)
>..

Functions that throw should allow std::terminate results, because
another throw could happen. IMO, function should avoid throw in
the general case.

IJ. Wang

VSR

unread,
May 10, 2006, 2:36:34 PM5/10/06
to
> Did you post the correct article reference. If so, did you actually
> read it? That seems to me to be mainly about whether or not you should
> use function try blocks. And indeed it contains this paragraph:

I probably should not have included the link to Herb Sutter's article
:-)

But my contention was not "How can a constructor denote an error
condition" but rather "do we need to design classes that depend on
exceptions thrown from constructors".


> There are more elegant ways to design classes than just throwing from
> ctors -


>> That is a pretty meaningless statement.

Well may be I am old school - but in my opinion, there are two
scenarios:

1. The class is darned simplistic, like the one that stores an IP
address. In this case, the exception is being thrown not because
"something went wrong" but merely as a convenient "Validation of IP"
mechanism. IN these scenarios, I would rather build a class factory
whose job is to validate the IP "before" creating the IP Class and
throw "before" the IP class is even created. I understand the
ramifications of using a class factory and losing out on the ability to
use objects on the stack (which I believe is the mostly used mechanism
for implementing RAII).

2. The class is not simple and does a lot of initializations. In real
life scenarios, a lot of times all the resources used by a class are
not used all the time. Parts of a class could be constructed on a first
use basis. So it is probably not meaningless in my opinion to defer
creation of internal resources to after class construction.

I read the article and I was using it to show the 'cons' of using
exceptions from ctors as a design principle.

There is no contention on the fact that "Throwing exceptions is the
only good way to signal an error during construction" - my point was
only that of "Do we need to design classes that depend on ctors
throwing up"...

-Vinayak

w...@seed.net.tw

unread,
May 10, 2006, 2:41:28 PM5/10/06
to
Bob Bell wrote:
>> a constructor that throws never lets the object to be created - no
>> object created = no destructor invoked.

> If the constructor for some class C throws, the C destructor is not
> called, but the destructors of all its members and bases *are* called.

Plus, only if a matching handler is found [15.3.9]

>> There are more elegant ways to design classes than just throwing from
>> ctors -

> Maybe you could outline them, because I'm unaware of a more elegant
> strategy than preventing an object from existing when its invariants
> can't be established.
>
>> throwing from ctor may be OK for really simple classes that are just
>> placeholders - like the IP class someone was talking about.
>
>> Just for your reference, here is a nice discussion about this
>> topic by
>> one of the industry experts in C++ -
>
>> http://www.gotw.ca/publications/mill13.htm
>
> This article doesn't seem to support in any way the notion that
> constructors shouldn't throw, and in fact I've read many other
> articles
> by Herb where he explicitly says throwing from constructors is a good
> idea.

"throwing from constructors is a good idea" is confusing for
many programmers. It is good because that is what the language is.
It is not so good because functions that throw may terminate.
There is dilemma, but that is what it is, IMO.

IJ. Wang

kanze

unread,
May 10, 2006, 5:01:26 PM5/10/06
to
David Abrahams wrote:
> "alfredo...@gmail.com" <alfredo...@gmail.com> writes:

> > the very event of an exception is ugly in the first place

> That is an attitude I've had some success in changing.

Note that you don't necessarily have to change it. All you have
to do (and in my case, have done) is show that the alternatives
are even uglier.

Or looking at it from the other side: it's not enough to show
that exceptions are bad, wrong or ugly. If you want to argue
against them, you have to show an alternative which is less bad,
less wrong or less ugly.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

kanze

unread,
May 10, 2006, 5:01:48 PM5/10/06
to
Andrei Alexandrescu (See Website For Email) wrote:

[...]


> > IMHO Flags-and-Resets are not so bad after
> > all (and I rather prefer to use a flag than to make a non-sensical
> > default constructor).

> Flags and Resets have their value. If your default constructor
> can't put an object in a meaningful state, and if you want to
> create arrays, there's no other way.

It's also a reasonable idiom if the error can reappear after
construction (so you have to systematically test anyway), or --
as is his case -- you can correct it and continue working. If
the idea is that in case of error, you change some parameters
and try again, then there is a strong argument for not setting
those parameters in the constructor, but later, with a function
which has a return code. In his case, for example, you might
want to only set the function in the constructor, and use a
separate function with a return code to set the bracket size.
His code would then become something like:

root_finder rf( f ) ;
double offset = 0.0 ;
while ( rf.set_brackets( lb - offset, ub + offest ) != ok ) {
offset += 1.0 ;
}
// ...

None of which means that exceptions from constructors are a bad
thing in general, of course -- my general logic for deciding
would be something along the lines of:

-- if the constructor cannot fail in its attempts to construct
a valid object, it shouldn't throw an exception,

-- otherwise, if the valid state cannot be guaranteed for the
lifetime of the object, you need some sort of flags anyway,

-- otherwise, exceptions seem the only reasonable solution.

The first condition is, of course, the ideal goal. But it isn't
always achievable.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Andrei Alexandrescu (See Website For Email)

unread,
May 11, 2006, 1:51:56 PM5/11/06
to
VSR wrote:
> But my contention was not "How can a constructor denote an error
> condition" but rather "do we need to design classes that depend on
> exceptions thrown from constructors".

I think the hubbub generated by this thread (and which I believe will
continue some more) has a lot to do with psychology. Our trade is full
of tradefoffs, rules that never fully apply, qualified truths, further
qualifications to those qualifications, and subjective opinion. In such
a setting, good solid "win-win" things that everybody agrees on are in
very short supply. Naturally, people don't feel good when someone
attacks one of these strongholds without bringing good arguments.

> Well may be I am old school - but in my opinion, there are two
> scenarios:
>
> 1. The class is darned simplistic, like the one that stores an IP
> address. In this case, the exception is being thrown not because
> "something went wrong" but merely as a convenient "Validation of IP"
> mechanism. IN these scenarios, I would rather build a class factory
> whose job is to validate the IP "before" creating the IP Class and
> throw "before" the IP class is even created.

This is pretty much what happens with a constructor that throws. The
destructor won't be invoked if the constructor fails, which further
supports that view.

> 2. The class is not simple and does a lot of initializations. In real
> life scenarios, a lot of times all the resources used by a class are
> not used all the time. Parts of a class could be constructed on a
> first
> use basis. So it is probably not meaningless in my opinion to defer
> creation of internal resources to after class construction.

Definitely. Sometimes you don't even have the information needed during
construction, or you can't pass it because you want to create arrays
etc. But that doesn't undermine the idea that it's worth designing
classes respecting their own invariants.

> There is no contention on the fact that "Throwing exceptions is the
> only good way to signal an error during construction" - my point was
> only that of "Do we need to design classes that depend on ctors
> throwing up"...

I believe that point is yet to be made. Given the arguments vehiculated
so far, the more reasonable question is "Do we need to design
constructors that obstinately won't throw?"


Andrei

kanze

unread,
May 11, 2006, 7:05:27 PM5/11/06
to
VSR wrote:

> Well may be I am old school - but in my opinion, there are two
> scenarios:

It would be nice if the world were that simple...

> 1. The class is darned simplistic, like the one that stores an
> IP address. In this case, the exception is being thrown not
> because "something went wrong" but merely as a convenient
> "Validation of IP" mechanism. IN these scenarios, I would
> rather build a class factory whose job is to validate the IP
> "before" creating the IP Class and throw "before" the IP class
> is even created. I understand the ramifications of using a
> class factory and losing out on the ability to use objects on
> the stack (which I believe is the mostly used mechanism for
> implementing RAII).

Conceptually, something like an IP should be a value oriented
object, with support for copy and assignment. As such, it
should almost never be allocated dynamically -- it's either a
local variable, or a member of a more complex object (and often,
it is a temporary).

On the other hand, I agree that in this particular case (and in
fact, any time a constructor may involve parsing user input),
exceptions aren't the most elegant method. Better alternatives
would involve a static IP::isValid() function, which returned
true or false, and considering the validity of the string as a
precondition to the constructor (with an assertion failure if
the string wasn't valid), or having a static factory function
which returned an IP object (by value -- not dynamically
allocated). But the reason for these choices isn't that
exceptions from constructors are bad, per se, but that
exceptions are generally not the most appropriate manner to
report syntax errors in user input. (Note that the isValid
static function has a second advantage: if you have a more
complex string in user input, you can completely validate it
without constructing a single object. If the user input also
contains objects which are more complex that IP, this could be
an important consideration.)

> 2. The class is not simple and does a lot of initializations.
> In real life scenarios, a lot of times all the resources used
> by a class are not used all the time. Parts of a class could
> be constructed on a first use basis. So it is probably not
> meaningless in my opinion to defer creation of internal
> resources to after class construction.

In some cases, perhaps. But in general, lazy construction
implies that construction errors can occur (and must be dealt
with) any time you use the object, and not just when it is
constructed. This complicates use of the object considerably,
and should be avoided except when necessary.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

ThosRTanner

unread,
May 11, 2006, 7:10:08 PM5/11/06
to

VSR wrote:
> But my contention was not "How can a constructor denote an error
> condition" but rather "do we need to design classes that depend on
> exceptions thrown from constructors".
You can design classes that don't depend on exceptions, but then you
get into testing flags to see if construction happened, which is
dangerous.

>
> > There are more elegant ways to design classes than just throwing from
> > ctors -
>
>
> >> That is a pretty meaningless statement.

OK, I admit that may have been a bit hard.

> Well may be I am old school - but in my opinion, there are two
> scenarios:
>
> 1. The class is darned simplistic, like the one that stores an IP
> address. In this case, the exception is being thrown not because
> "something went wrong" but merely as a convenient "Validation of IP"
> mechanism. IN these scenarios, I would rather build a class factory
> whose job is to validate the IP "before" creating the IP Class and
> throw "before" the IP class is even created. I understand the
> ramifications of using a class factory and losing out on the ability to
> use objects on the stack (which I believe is the mostly used mechanism
> for implementing RAII).

That appears to be a hell of a lot of overhead to avoid an exception.
What would you return from your factory - a pointer to the created
class or NULL presumably? That still means the client needs to check
for NULL, which is a) an overhead and b) frequently forgotton "because
it will never ever go wrong". One of the uses of exceptions is to
ensure that clients CAN'T ignore a problem.

> 2. The class is not simple and does a lot of initializations. In real
> life scenarios, a lot of times all the resources used by a class are
> not used all the time. Parts of a class could be constructed on a first
> use basis. So it is probably not meaningless in my opinion to defer
> creation of internal resources to after class construction.

That's a slightly different issue. If you don't need parts of the data
till subsequently (like for instance a vector, which can extend
itself), then clearly you don't need to create them until you use them,
although you still have to handle any errors when they happen. It's
easier to code v[i] = 5 and let someone who has a try block deal with
the errors than it is to do if (v.assign(i, 5) != SUCCEEDED) then {
deal with error };

> I read the article and I was using it to show the 'cons' of using
> exceptions from ctors as a design principle.
>
> There is no contention on the fact that "Throwing exceptions is the
> only good way to signal an error during construction" - my point was
> only that of "Do we need to design classes that depend on ctors
> throwing up"...

You don't need to, but I suspect it'll result in a lot of extra work in
design and coding.

john...@yahoo.com

unread,
May 11, 2006, 7:46:55 PM5/11/06
to
VSR wrote:

> There is no contention on the fact that "Throwing exceptions is the
> only good way to signal an error during construction" - my point was
> only that of "Do we need to design classes that depend on ctors
> throwing up"...

It seems to me that this boils down to: "Should we avoid designing
classes which guarantee invariants which cannot be proven to hold at
compile time?" If we avoid throwing constructors entirely, we limit
ourselves to class invariants which can be checked at compile time.

I think what Dave Abrahams and others have been arguing is that it is
often very convenient to design classes which enforce a wider range of
invariants than those that can be checked at compile time.

kanze

unread,
May 12, 2006, 8:00:49 AM5/12/06
to
john...@yahoo.com wrote:
> VSR wrote:

> > There is no contention on the fact that "Throwing exceptions
> > is the only good way to signal an error during construction"
> > - my point was only that of "Do we need to design classes
> > that depend on ctors throwing up"...

> It seems to me that this boils down to: "Should we avoid
> designing classes which guarantee invariants which cannot be
> proven to hold at compile time?" If we avoid throwing
> constructors entirely, we limit ourselves to class invariants
> which can be checked at compile time.

Not really. We can always use assert, and abort if the class
cannot respect its invariants. If it is reasonably possible for
the user to verify before hand that his proposed arguments will
allow the class to respect its invariants, then this can even be
a preferred alternative. Such checks are not always possible,
however, and even when possible, may have unacceptable overhead.

> I think what Dave Abrahams and others have been arguing is
> that it is often very convenient to design classes which
> enforce a wider range of invariants than those that can be
> checked at compile time.

Or that sometimes, it isn't really reasonable, or even possible,
to impose a preliminary check by the client code.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

john...@yahoo.com

unread,
May 12, 2006, 8:24:33 PM5/12/06
to
kanze wrote:

> Not really. We can always use assert, and abort if the class
> cannot respect its invariants. If it is reasonably possible for
> the user to verify before hand that his proposed arguments will
> allow the class to respect its invariants, then this can even be
> a preferred alternative.

I'm not sure I see when abort would be preferable to throwing an
exception. Can you elaborate or illustrate?

(Also, do those who object to constructors that throw find aborting a
preferable alternative?)

David Abrahams

unread,
May 13, 2006, 7:18:44 AM5/13/06
to
"kanze" <ka...@gabi-soft.fr> writes:

> john...@yahoo.com wrote:
>> VSR wrote:
>
>> > There is no contention on the fact that "Throwing exceptions
>> > is the only good way to signal an error during construction"
>> > - my point was only that of "Do we need to design classes
>> > that depend on ctors throwing up"...
>
>> It seems to me that this boils down to: "Should we avoid
>> designing classes which guarantee invariants which cannot be
>> proven to hold at compile time?" If we avoid throwing
>> constructors entirely, we limit ourselves to class invariants
>> which can be checked at compile time.
>
> Not really. We can always use assert, and abort if the class
> cannot respect its invariants.

Yeah, but that turns the conditions for establishing the invariant
into preconditions...

> If it is reasonably possible for the user to verify before hand that
> his proposed arguments will allow the class to respect its
> invariants, then this can even be a preferred alternative. Such
> checks are not always possible, however, and even when possible, may
> have unacceptable overhead.

....which is why it may be a bad idea to make them preconditions. So
you're left with either exceptions, or weakening the class invariants.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Francis Glassborow

unread,
May 13, 2006, 4:39:54 PM5/13/06
to
In article <1147438343.6...@g10g2000cwb.googlegroups.com>,
"john...@yahoo.com" <john...@yahoo.com> writes

>I'm not sure I see when abort would be preferable to throwing an
>exception. Can you elaborate or illustrate?
>
>(Also, do those who object to constructors that throw find aborting a
>preferable alternative?)

I would be stronger on this issue. I think aborting in library code (or
other code intended for reuse) is generally unacceptable. Abort is fine
in application specific code. If some library code cannot complete
successfully it should use some non-fatal error reporting/handling
technique. Sometimes returning an error code is a reasonable design
option, at other times throwing an exception would be better. If there
is a way for local recovery then that should be attempted first.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

James Kanze

unread,
May 14, 2006, 1:51:46 PM5/14/06
to
Francis Glassborow wrote:
> In article <1147438343.6...@g10g2000cwb.googlegroups.com>,
> "john...@yahoo.com" <john...@yahoo.com> writes
>> I'm not sure I see when abort would be preferable to throwing
>> an exception. Can you elaborate or illustrate?

>> (Also, do those who object to constructors that throw find
>> aborting a preferable alternative?)

> I would be stronger on this issue. I think aborting in library
> code (or other code intended for reuse) is generally
> unacceptable. Abort is fine in application specific code. If
> some library code cannot complete successfully it should use
> some non-fatal error reporting/handling technique. Sometimes
> returning an error code is a reasonable design option, at
> other times throwing an exception would be better. If there is
> a way for local recovery then that should be attempted first.

Do you prefer the typical current solution: undefined behavior?
Library code is no different than anything else -- it defines a
contract. If client code violates that contract, then nothing
else goes. The alternative to aborting is generally undefined
behavior. If client code cannot accept an abort, it has a
simple solution: respect the contract.

Of course, I see nothing wrong with providing a callback (which
aborts by default). There are cases where, even in the case of
an abort, you want to do some minimal clean up first. But in no
case should the program be allowed to continue as if nothing had
gone wrong.

--
James Kanze kanze...@neuf.fr


Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung

9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

w...@seed.net.tw

unread,
May 14, 2006, 1:53:13 PM5/14/06
to
Francis Glassborow wrote:
>...

>I would be stronger on this issue. I think aborting in library code (or
>other code intended for reuse) is generally unacceptable. Abort is fine
>in application specific code. If some library code cannot complete
>successfully it should use some non-fatal error reporting/handling
>technique. Sometimes returning an error code is a reasonable design
>option, at other times throwing an exception would be better. If there
>is a way for local recovery then that should be attempted first.

Function that throw may just lead to unexpected terminate (or abort)
I think the programming style "anything wrong, throw exception"
may be practical(make it really rare) but correct if terminate is
absolutely undesirable (another bad thing is the class name
'exception').

IJ. Wang

James Kanze

unread,
May 14, 2006, 1:51:11 PM5/14/06
to
john...@yahoo.com wrote:
> kanze wrote:

>> Not really. We can always use assert, and abort if the class
>> cannot respect its invariants. If it is reasonably possible
>> for the user to verify before hand that his proposed
>> arguments will allow the class to respect its invariants,
>> then this can even be a preferred alternative.

> I'm not sure I see when abort would be preferable to throwing
> an exception. Can you elaborate or illustrate?

Anytime you violate a precondition, or otherwise find a
programming error. Exceptions are designed for cases where you
can abort some part of the processing without affecting the rest
of the program -- for example, in a server, you might abort
processing a request because it was too complicated (and
resulted in bad_alloc), but that doesn't mean you have to refuse
all future requests (supposing, of course, that you backed out
of the aborted request correctly).

If you detect a programming error, this is NOT the case --
there's no way to back out and correct the code. So about all
you can reasonably do is abort.

> (Also, do those who object to constructors that throw find
> aborting a preferable alternative?)

That's a different question. I use three types of error
reporting: return codes, exceptions and aborting. Return codes,
when the error is more or less to be expected from time to time
in the course of normal processing, and it is reasonable to
think that at least in some cases, it can be handled
immediately ; exceptions, when the error probably won't normally
occur, or signifies a problem at a higher level, which almost
certainly requires backing out of a complex operation, and abort
when I detect an "impossible" condition -- something which
logically couldn't have happened. Furthermore, I'll sometimes
use exceptions in the first case, particularly if the error
would normally be detected in a constructor -- it's nice to say
that a return code would be ideal, but constructors don't have
return codes, and even if they did, you would still be left with
an object in an incoherent state.

--
James Kanze kanze...@neuf.fr


Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung

9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

James Kanze

unread,
May 14, 2006, 1:52:30 PM5/14/06
to
David Abrahams wrote:
> "kanze" <ka...@gabi-soft.fr> writes:

>> john...@yahoo.com wrote:
>>> VSR wrote:

>>>> There is no contention on the fact that "Throwing
>>>> exceptions is the only good way to signal an error during
>>>> construction" - my point was only that of "Do we need to
>>>> design classes that depend on ctors throwing up"...
>>> It seems to me that this boils down to: "Should we avoid
>>> designing classes which guarantee invariants which cannot be
>>> proven to hold at compile time?" If we avoid throwing
>>> constructors entirely, we limit ourselves to class
>>> invariants which can be checked at compile time.

>> Not really. We can always use assert, and abort if the class
>> cannot respect its invariants.

> Yeah, but that turns the conditions for establishing the
> invariant into preconditions...

Exactly:-).

>> If it is reasonably possible for the user to verify before
>> hand that his proposed arguments will allow the class to
>> respect its invariants, then this can even be a preferred
>> alternative. Such checks are not always possible, however,
>> and even when possible, may have unacceptable overhead.

> ....which is why it may be a bad idea to make them
> preconditions. So you're left with either exceptions, or
> weakening the class invariants.

Ideally, most of the time, they probably should be
preconditions. If you don't have the necessaries to create an
object, don't. In practice, this often creates more problems
than it is worth, of course, and exceptions are the lesser of
two evils.

Consider the simple example of an IP class, which has a
constructor from a string. At my last client site, I
implemented such -- and made it a pre-condition that the string
had the legal format. This meant that 1) I also had to provide
a static member function to test it, and 2) most of the time,
the code would try to match the regular expression twice, once
in the static isValid function, and a second time in the assert
in the constructor. The first is not really a problem; it
doesn't mean any duplication of code, because of course, the
constructor also called the static function. The second, on the
other hand, can have a significant impact on performance. In my
case, no problem: the only time we actually constructed IP's
from strings was when reading the configuration file, a total of
five or six times at program start up. Not ever program has it
so simple, however, and leaving all checking until the
constructor, and then raising an exception, is certainly a lot
faster. Even if it is a question of a syntax error which you
would normally expect to be handled not to far from the place
where it was detected.

--
James Kanze kanze...@neuf.fr


Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung

9 place Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34

David Abrahams

unread,
May 14, 2006, 7:12:14 PM5/14/06
to
James Kanze <kanze...@neuf.fr> writes:

>>> If it is reasonably possible for the user to verify before
>>> hand that his proposed arguments will allow the class to
>>> respect its invariants, then this can even be a preferred
>>> alternative. Such checks are not always possible, however,
>>> and even when possible, may have unacceptable overhead.
>
>> ....which is why it may be a bad idea to make them
>> preconditions. So you're left with either exceptions, or
>> weakening the class invariants.
>
> Ideally, most of the time, they probably should be
> preconditions. If you don't have the necessaries to create an
> object, don't.

When, as in my writing above, "they" refers to conditions that may not
be possible or practical for the caller to check or ensure, they
should not be preconditions.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

David Abrahams

unread,
May 14, 2006, 7:13:28 PM5/14/06
to
w...@seed.net.tw writes:

> Francis Glassborow wrote:
>>...
>>I would be stronger on this issue. I think aborting in library code (or
>>other code intended for reuse) is generally unacceptable. Abort is fine
>>in application specific code. If some library code cannot complete
>>successfully it should use some non-fatal error reporting/handling
>>technique. Sometimes returning an error code is a reasonable design
>>option, at other times throwing an exception would be better. If there
>>is a way for local recovery then that should be attempted first.
>
> Function that throw may just lead to unexpected terminate (or abort)
> I think the programming style "anything wrong, throw exception"

Nobody recommends that. There's a fairly well-developed understanding
about when and where an exception is appropriate. A large fraction of
"anything wrong" conditions should be handled by some form of
assertion, rather than an exception.

> may be practical(make it really rare) but correct if terminate is
> absolutely undesirable (another bad thing is the class name
> 'exception').

How do you figure?

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

Francis Glassborow

unread,
May 14, 2006, 7:19:08 PM5/14/06
to
In article <e47i7o$1go$1...@emma.aioe.org>, James Kanze
<kanze...@neuf.fr> writes

>Of course, I see nothing wrong with providing a callback (which
>aborts by default). There are cases where, even in the case of
>an abort, you want to do some minimal clean up first. But in no
>case should the program be allowed to continue as if nothing had
>gone wrong.

Which is why I prefer throwing an exception.

I once saw an implementation of operator>>(std::istream &, mytype &)
which aborted if the input was bad. I believe today as I did then, that
this is bad design. Yes, input can fail to meet the requirements of a
type but aborting a program because that has happened is not the correct
solution.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

wrybred

unread,
May 14, 2006, 7:37:53 PM5/14/06
to
kanze wrote:

> Not really. We can always use assert, and abort if the class
> cannot respect its invariants. If it is reasonably possible for
> the user to verify before hand that his proposed arguments will
> allow the class to respect its invariants, then this can even be
> a preferred alternative. Such checks are not always possible,
> however, and even when possible, may have unacceptable overhead.

Except when we can't assert(). Assert often falls out in release builds
(e.g., glibc and MSVCRT), leaving an unchecked value. Asserts are a
nice debugging tool, but in production code they're usually not
appropriate because of their overhead. Asserts are less of a favor to
the client and more of a favor to the library writer (except of course
where the client is doing ownership-related things, like freeing
memory).

Default and copy constructed objects should generally be
exception-safe. They're not usually invoked with resource acquisition
beyond deep copies of memory-managed objects--though often they're
invoked with resource sharing. So, ideally they can be optimized,
making them good candidates for std containers, producter/consumer work
queues, etc.

That leaves constructors taking non-trivial parameters, which tend to
be exercised more in IO-related and other non-critical-path activies,
where the performance overhead of throwing is less of a concern anyway.

David Abrahams

unread,
May 15, 2006, 8:02:54 AM5/15/06
to
Francis Glassborow <fra...@robinton.demon.co.uk> writes:

> In article <e47i7o$1go$1...@emma.aioe.org>, James Kanze
> <kanze...@neuf.fr> writes
>

> Which is why I prefer throwing an exception.
>
> I once saw an implementation of operator>>(std::istream &, mytype &)
> which aborted if the input was bad. I believe today as I did then, that
> this is bad design. Yes, input can fail to meet the requirements of a
> type but aborting a program because that has happened is not the correct
> solution.

Which is why you don't make correct user input a precondition.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]

w...@seed.net.tw

unread,
May 15, 2006, 8:17:12 AM5/15/06
to
David Abrahams wrote:
>..

>> may be practical(make it really rare) but correct if terminate is
>> absolutely undesirable (another bad thing is the class name
>> 'exception').

>How do you figure?

I regard the throw as one of last resort of error handling provided
by the language, anything falls between is basically users codes
(nothing to do with the very throw itself)

We should not assign the failure semantics to the throw expression
to the extent that it implies no further failure since after, and
the core language simply just does what it does.
I myself try to use the throw as neutral as possible to mean
stack unwind (may exit, may be intercepted). So far it is good to
mean general error, may be better or worse than terminate.

Error handling is too fundamental to the language for me to think
anything too different than currently is (I'm just a C++ user),
e.g. what about to have another kind of throw that just unwind the
stack without the embeded termination, or what about an empty base
exception class...such imaginary,etc. (my current error handling
approach is for the thrown object to be identifiable so the function
can catch it and convert to return).

Actually, we cannot really talk about error and correction in the
general semantics, there should be a different name.

Error handling is a system wise consideration. Anything different
may form another different system.

That's about what I am at and can recall.

IJ. Wang

kanze

unread,
May 15, 2006, 2:55:19 PM5/15/06
to
Francis Glassborow wrote:
> In article <e47i7o$1go$1...@emma.aioe.org>, James Kanze
> <kanze...@neuf.fr> writes
> >Of course, I see nothing wrong with providing a callback
> >(which aborts by default). There are cases where, even in
> >the case of an abort, you want to do some minimal clean up
> >first. But in no case should the program be allowed to
> >continue as if nothing had gone wrong.

> Which is why I prefer throwing an exception.

An exception is not minimal cleanup. It involves calling all
the destructors, all the way up the stack. And risking that the
user try to continue when you know that it is impossible.

> I once saw an implementation of operator>>(std::istream &,
> mytype &) which aborted if the input was bad. I believe today
> as I did then, that this is bad design. Yes, input can fail to
> meet the requirements of a type but aborting a program because
> that has happened is not the correct solution.

That's obviously a different issue. You expect bad input; bad
input isn't a programmer error. I'd argue that even an
exception is too much here -- this is the sort of everyday
problem which should typically be handled by return codes.

--
James Kanze GABI Software

Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung

9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

kanze

unread,
May 15, 2006, 2:57:10 PM5/15/06
to
wrybred wrote:
> kanze wrote:

> > Not really. We can always use assert, and abort if the
> > class cannot respect its invariants. If it is reasonably
> > possible for the user to verify before hand that his
> > proposed arguments will allow the class to respect its
> > invariants, then this can even be a preferred alternative.
> > Such checks are not always possible, however, and even when
> > possible, may have unacceptable overhead.

> Except when we can't assert(). Assert often falls out in
> release builds (e.g., glibc and MSVCRT), leaving an unchecked
> value.

Since when? I've never had assert "fall out" with g++ or with
VC++. And I've never had delivered production code without all
assert's active.

> Asserts are a nice debugging tool, but in production code
> they're usually not appropriate because of their overhead.

And testing the condition to raise an exception doesn't have the
same overhead?

It would help if people would read what I wrote. I said simply
that one way a class can ensure its invariants is by moving them
out as pre-conditions. I then immediately clarified that it
isn't always possible, even in cases where it might be a good
idea.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Francis Glassborow

unread,
May 15, 2006, 2:53:01 PM5/15/06
to
In article <1147567395.5...@v46g2000cwv.googlegroups.com>,
wrybred <wry...@gmail.com> writes

>Default and copy constructed objects should generally be
>exception-safe.

Generally, perhaps but the copy ctor of any type that acquires resources
(not just memory) has the potential of failing because the resource has
been exhausted. It seems to me that the correct way to handle such cases
is by throwing an exception. If the process will be unable to continue
then it should catch the exception and terminate the program in whatever
way the programmer has determined.

Even default ctors for types that own resources can fail because
resource limits have been exceeded.

I would hazard a guess that most types whose instances own resources
must have ctors that can throw.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

w...@seed.net.tw

unread,
May 15, 2006, 3:01:45 PM5/15/06
to
john...@yahoo.com wrote:
>..

>(Also, do those who object to constructors that throw find aborting a
>preferable alternative?)

I do not object for constructors to throw (nearly all pimpl classes
have to fail for lack of memory) but I find many of my objects
that are created before main() will abort in failure.

IJ. Wang

Francis Glassborow

unread,
May 16, 2006, 9:47:18 PM5/16/06
to
In article <1147687438.1...@i39g2000cwa.googlegroups.com>,
kanze <ka...@gabi-soft.fr> writes

> >That's obviously a different issue. You expect bad input; bad
> >input isn't a programmer error. I'd argue that even an
> >exception is too much here -- this is the sort of everyday
> >problem which should typically be handled by return codes.

Which you well know is not an available solution when using operators.


--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions:
http://www.spellen.org/youcandoit/projects

0 new messages