Throwing exceptions from copy constructor 
July 23rd, 2005, 04:59 AM
| | | Throwing exceptions from copy constructor
People say that is a bad technique to throw exception from
constructors; and that the solution would be to create a function
_create_ to initialize an object.
What about copy constructors? How can we avoid throwing exceptions? If
we already have an abject witch was initialized wit _create_ we will be
forced to call create in copy constructor and to throw exceptions from
it.
Have a nice day,
Mihai. | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
>People say that is a bad technique to throw exception from constructors
In an ideal world, constructors would never throw. In the real world,
that's not the case. Whether bad technique or not (I won't step on a
slippery slope like that), a non-trivial class will likely see a
situation where it could need to catch an exception caused by
construction of either a base class or one of the data members, and not
be able to reasonably handle it.
What would you do in that case? Complain that throwing from
constructors is bad style and do nothing? Sure, you could use a create
function to initialize the object, but if you call it in the
constructor and it throws, you're back to square one. That leaves
calling it outside of the constructor, which basically means that you
either require the client code to call it (a dangerous plan), or you
work out some ugly hack where create is only called for the first use
beyond the constructor.
What about default initialization? It's feasable that default
initialization could fail, and since that constitutes an exceptional
situation, the constructor could throw (bad style or not). So you find
yourself between a rock and a hard place with the ideal world and the
real world. And here's the bad news: The real world always wins.
This includes the copy constructor and in some cases the assignment
operator as well. I hate to say that you're SOL, but them's the breaks. | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
"mihai" <Mihai.Grecu@gmail.com> wrote in message
news:1117712863.931778.290700@g44g2000cwa.googlegr oups.com[color=blue]
> People say that is a bad technique to throw exception from
> constructors; and that the solution would be to create a function
> _create_ to initialize an object.
>
> What about copy constructors? How can we avoid throwing exceptions? If
> we already have an abject witch was initialized wit _create_ we will
> be forced to call create in copy constructor and to throw exceptions
> from it.[/color]
I don't believe that well-informed people say constructors shouldn't throw.
They do say that *destructors* shouldn't throw.
The throwing of an exception by a constructor can cause a problem because it
means that the destructor is not called, which may mean that necessary
cleanup doesn't occur.
The standard way to handle this is to wrap anything in class A that needs to
be cleaned up in a class of its own (say, classes B, C and D) and then make
objects of those classes (say, b, c and d) members of A. The initialisation
of b, c and d can then occur in A's constructor (via the initialisation
list). If, say, the initialisation of d causes an exception, then b and c
will have been fully constructed (unlike the A object) and hence their
destructors will be called, even though the A object's constructor won't be.
This achieves the necessary cleanup.
The C++ FAQ on Exceptions and Error Handling has some useful stuff on this: http://www.parashift.com/c++-faq-lite/exceptions.html
--
John Carson | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
IMHO, that's silly ( saying that it's bad technique to throw from a
constructor ). What other mechanism is there to know if something goes
wrong with contructing an object? You can't return an error code from
the constructor, all you can do is throw an exception. Who said that
this is bad technique anyway? | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
* BigBrian:[color=blue]
>
> IMHO, that's silly ( saying that it's bad technique to throw from a
> constructor ).[/color]
Yes.
[color=blue]
> What other mechanism is there to know if something goes
> wrong with contructing an object?[/color]
An infinite number... ;-)
[color=blue]
> You can't return an error code from the constructor, all you can do is
> throw an exception.[/color]
Nope.
class Silly
{
private:
bool iAmValid;
public:
Silly( int x, bool& ok ): iAmValid( x == 42 )
{
ok = iAmValid;
}
};
The reason why this _particular_ technique is bad is mainly that you risk
having invalid objects hanging around, so called ZOMBIE OBJECTS, which
necessitates much redundant checking of validity and leads to bugs.
Formally it's a kind of meta, second-level class invariant.
Worth noting: languages like Java and C# typically force you to have
zombie objects but in those languages the problem arises from the other end
of the object lifecycle, destruction. Because you don't have deterministic
destruction in those languages the programmer must call Dispose (or like)
methods explicitly, and the objects still exist afterwards. And so must
note for themselves that they're no longer valid, and so they're zombies
and can conceivably become zombies earlier on.
Also worth noting: handling of external resources in some cases require
zombie states. E.g., a file can become invalid at any time. An object
wrapping that file is then logically invalid for at least part of its
interface, a zombie object wrt. to the invalid parts of the interface.
[color=blue]
> Who said that [throwing an exception] is bad technique anyway?[/color]
Yes. Anyone worth listening to will tell the opposite. A clear but
limited discussion of why using exceptions in constructors, avoiding
zombie states, is given in Bjarne Stroustrup's TCPPPL appendix on
exception safety in the standard library, available as a PDF document
at <url: http://www.research.att.com/~bs/3rd_safe0.html>.
--
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? | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
"mihai" <Mihai.Grecu@gmail.com> wrote in message
news:1117712863.931778.290700@g44g2000cwa.googlegr oups.com...[color=blue]
> People say that is a bad technique to throw exception from
> constructors; and that the solution would be to create a function
> _create_ to initialize an object.[/color]
The so called bad technique is throwing exception from destructors, not
constructors.
[color=blue]
>
> What about copy constructors? How can we avoid throwing exceptions? If
> we already have an abject witch was initialized wit _create_ we will be
> forced to call create in copy constructor and to throw exceptions from
> it.[/color]
There are many ways like turning your object into a zombie state. Read the
FAQ, it describes some of the techniques.
Of course, throwing exceptions from copy consturcotrs is what most would
recommend.
[color=blue]
>
> Have a nice day,
> Mihai.
>[/color] | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
Yes, I guess somebody could do something like your Silly class, however
since it has problems I didn't consider this when I made my statement
about "what other mechanism exist (for notifying the client code that
an error has occured in a constructor)". In using the Silly class, the
calling code may not check the pass by reference value into this
constructor. Also, the silly class will need a bunch of if tests
throughout it's implementation.
Since you said there are infinitely many ways to provide this
mechanism, and the Silly class is clearly not the way to do it. Please
provide another method which is better than throwing an exception.
I understand that some objects need memebers to keep track of some sort
of state, and that state may at times be invalid. This is different
than error conditions which need to throw exceptions to notify the
calling code that something is wrong. | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
>The so called bad technique is throwing exception from destructors, not
constructors.
I thought throwing an exception from a destructor was *MUCH* worse than
bad technique, it's plain outright WRONG. Aren't destructors REQUIRED
to NOT throw? | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
* BigBrian:[color=blue]
> Yes, I guess somebody could do something like your Silly class, however
> since it has problems I didn't consider this when I made my statement
> about "what other mechanism exist (for notifying the client code that
> an error has occured in a constructor)". In using the Silly class, the
> calling code may not check the pass by reference value into this
> constructor. Also, the silly class will need a bunch of if tests
> throughout it's implementation.[/color]
That's about right.
[color=blue]
> Since you said there are infinitely many ways to provide this
> mechanism, and the Silly class is clearly not the way to do it. Please
> provide another method which is better than throwing an exception.[/color]
You'll need to define "better" first.
But it's evident that you've misunderstood and skipped some points, so
there's no real need for that: do read my posting again.
[color=blue]
> I understand that some objects need memebers to keep track of some sort
> of state, and that state may at times be invalid.[/color]
Yes, sort of.
[color=blue]
> This is different than error conditions which need to throw exceptions
> to notify the calling code that something is wrong.[/color]
No, it's all about convenience, maintainability, productivity and so forth.
There's no absolute "need", just as there is no absolute "better". Those
are subjective, contextual judgements, not technical facts, although I
agree that concerning this issue you'd need very strong reasons for using
anything but exceptions and be able to justify it to someone competent.
--
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? | 
July 23rd, 2005, 04:59 AM
| | | Re: Throwing exceptions from copy constructor
* BigBrian:[color=blue][color=green]
> > The so called bad technique is throwing exception from destructors, not
> > constructors.[/color]
>
> I thought throwing an exception from a destructor was *MUCH* worse than
> bad technique, it's plain outright WRONG. Aren't destructors REQUIRED
> to NOT throw?[/color]
No.
But a destructor for an object used in a standard collection is required
to not throw.
That's also the case for exception object destructors... ;-)
--
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? | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
>No.
[color=blue]
>But a destructor for an object used in a standard collection is required
>to not throw.[/color]
I don't this this is strict enough. Most techniques for writing
exception safe code assumes that destructors to NOT throw. | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
>You'll need to define "better" first.
It was implied that "better" meant without the stated problems with
your "Silly" class.
[color=blue]
>But it's evident that you've misunderstood and skipped some points,
> so, there's no real need for that: do read my posting again.[/color]
You (arogantly) said there were infinate ways to do this, and now you
won't provide another mechanism?
[color=blue]
> No, it's all about convenience, maintainability, productivity and so forth.
>There's no absolute "need", just as there is no absolute "better".[/color]
If the need to inform the user of a class that an error has occured is
a *requirement*, then there *is* an absolute need. This brings us back
to the issue... How else can you *guarentee* that the user of your
class knows (without a doubt) that an error has occured. Requiring the
user of your class to check a flag isn't good enough (due to the issues
that we already discoussed). What are the infinitely many other ways
to guarentte this is accomplish without throwing an exception? | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
* BigBrian:[color=blue][color=green]
> >No.[/color]
>[color=green]
> >But a destructor for an object used in a standard collection is required
> >to not throw.[/color]
>
> I don't this this is strict enough. Most techniques for writing
> exception safe code assumes that destructors to NOT throw.[/color]
You asked: "Aren't destructors REQUIRED to NOT throw?".
You get an answer to that, not to something else that you even now aren't
telling what is.
Please don't use all caps, please don't quote out of context, please
don't add your own imagined context to responses (I at least am not a
telepath: I don't know what the heck you're talking about).
--
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? | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
* BigBrian:[color=blue][color=green]
> >You'll need to define "better" first.[/color]
>
> It was implied that "better" meant without the stated problems with
> your "Silly" class.
>[color=green]
> >But it's evident that you've misunderstood and skipped some points,
> > so, there's no real need for that: do read my posting again.[/color]
>
> You (arogantly) said there were infinate ways to do this[/color]
The part "said there were infinate ways to do this" is a lie; the
"arogantly" is meaningless applied to something that hasn't happened.
Don't lie, don't insinuate.
You asked: "What other mechanism is there to know if something goes
wrong with contructing an object?"
You got the answer: "An infinite number... ;-)"
These include the Silly class way, abort, callback, global status
variable, factory with null-pointer result, even writing the result
to a file or sending an e-mail -- use your imagination.
[color=blue]
> and now you won't provide another mechanism?[/color]
If you can be more clear about the C++ question, I'll try to help you.
[color=blue][color=green]
> > No, it's all about convenience, maintainability, productivity and so forth.
> > There's no absolute "need", just as there is no absolute "better".[/color]
>
> If the need to inform the user of a class that an error has occured is
> a *requirement*, then there *is* an absolute need. This brings us back
> to the issue... How else can you *guarentee* that the user of your
> class knows (without a doubt) that an error has occured. Requiring the
> user of your class to check a flag isn't good enough (due to the issues
> that we already discoussed). What are the infinitely many other ways
> to guarentte this is accomplish without throwing an exception?[/color]
There are _no_ ways that guarantee that.
In particular, an exception doesn't guarantee that; client code can
always nullify any guarantee you think you have.
Foo* p; try{ p = new Foo; } catch(...){}
// No guarantee here.
Hth.,
- Alf
--
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? | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
On 2005-06-02 09:04:34 -0400, "John Carson"
<jcarson_n_o_sp_am_@netspace.net.au> said:
[color=blue]
> "mihai" <Mihai.Grecu@gmail.com> wrote in message
> news:1117712863.931778.290700@g44g2000cwa.googlegr oups.com[color=green]
>> People say that is a bad technique to throw exception from
>> constructors; and that the solution would be to create a function
>> _create_ to initialize an object.
>>
>> What about copy constructors? How can we avoid throwing exceptions? If
>> we already have an abject witch was initialized wit _create_ we will
>> be forced to call create in copy constructor and to throw exceptions
>> from it.[/color]
>
>
> I don't believe that well-informed people say constructors shouldn't
> throw. They do say that *destructors* shouldn't throw.
>
> The throwing of an exception by a constructor can cause a problem
> because it means that the destructor is not called, which may mean that
> necessary cleanup doesn't occur.[/color]
Just to clarify, the destructor of that class isn't called, but the
destructors of any already constructed superclasses are.
[color=blue]
> The standard way to handle this is to wrap anything in class A that
> needs to be cleaned up in a class of its own (say, classes B, C and D)
> and then make objects of those classes (say, b, c and d) members of A.
> The initialisation of b, c and d can then occur in A's constructor (via
> the initialisation list). If, say, the initialisation of d causes an
> exception, then b and c will have been fully constructed (unlike the A
> object) and hence their destructors will be called, even though the A
> object's constructor won't be. This achieves the necessary cleanup.
>
> The C++ FAQ on Exceptions and Error Handling has some useful stuff on this:
>
> http://www.parashift.com/c++-faq-lite/exceptions.html[/color]
--
Clark S. Cox, III clarkcox3@gmail.com | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
>The part "said there were infinate ways to do this" is a lie; the[color=blue]
>"arogantly" is meaningless applied to something that hasn't happened.[/color]
What! This isn't a lie. Here is a quote from one of your previous
message....
I wrote this....[color=blue][color=green]
>> What other mechanism is there to know if something goes
>> wrong with contructing an object?[/color][/color]
And you wrote this...[color=blue]
>An infinite number... ;-)[/color] | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
>In particular, an exception doesn't guarantee that; client code can[color=blue]
>always nullify any guarantee you think you have.[/color]
[color=blue]
>Foo* p; try{ p = new Foo; } catch(...){}
>// No guarantee here.[/color]
That's true. But in this case the user of the class has to
specifically add the above code to ignore the exception. In the case
of checking a return value, you have to specificially add code to check
it. It could be easy for the user of the class to forget to check for
an error. Thus, having to add code to say "I'm not intrested in your
error" is BETTER than writting code such that doing nothing saying same
thing ( as with an error flag ). | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
* BigBrian:[color=blue][color=green]
> >The part "said there were infinate ways to do this" is a lie; the
> >"arogantly" is meaningless applied to something that hasn't happened.[/color]
>
> What! This isn't a lie. Here is a quote from one of your previous
> message....
>
> I wrote this....[color=green][color=darkred]
> >> What other mechanism is there to know if something goes
> >> wrong with contructing an object?[/color][/color]
>
> And you wrote this...[color=green]
> >An infinite number... ;-)[/color][/color]
Ergo, you lied.
In addition to don't lie and don't insinuate:
Don't quote out of context.
--
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? | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
* BigBrian:[color=blue][color=green]
> >In particular, an exception doesn't guarantee that; client code can
> >always nullify any guarantee you think you have.[/color]
>[color=green]
> >Foo* p; try{ p = new Foo; } catch(...){}
> >// No guarantee here.[/color]
>
> That's true. But in this case the user of the class has to
> specifically add the above code to ignore the exception. In the case
> of checking a return value, you have to specificially add code to check
> it. It could be easy for the user of the class to forget to check for
> an error. Thus, having to add code to say "I'm not intrested in your
> error" is BETTER than writting code such that doing nothing saying same
> thing ( as with an error flag ).[/color]
Add a "usually" and that will be generally true.
However there are many ways the client code can foul up, e.g.
int x = 1;
std::cout << x++ << "," << x << std::endl;
// We have Undefined Behavior, so no guarantee here:
Foo object;
No matter which method is employed one can only help the client code
programmer, one can not guarantee correct client code. And with that
perspective what constitutes the best help depends on the client code
programmer. And much else.
As an example of relevant purely technical consideration, in language
agnostic code such as the basic COM infrastructure it's not possible
to throw C++ exceptions out of the the interface the client code uses,
since the client code language may not understand them. So this is a
situation where exceptions are not clearly "better". For this example
exceptions are most probably "worse"... ;-)
At a higher level, with a good choice of error reporting mechanism C++
exceptions can be added on top, in a wrapper layer, for C++ client code.
The reverse, starting out with C++ exceptions and wrapping them, would
introduce a possible internal overhead for no gain. What's "better"
and "worse" is therefore highly contextual, not absolutes.
--
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? | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
mihai wrote:[color=blue]
> People say that is a bad technique to throw exception from
> constructors; and that the solution would be to create a function
> _create_ to initialize an object.[/color]
Which people? Provided you know what you are doing, there is no problem.
[color=blue]
> What about copy constructors? How can we avoid throwing exceptions? If
> we already have an abject witch was initialized wit _create_ we will be
> forced to call create in copy constructor and to throw exceptions from
> it.[/color]
It's more important to be exception-neutral. You can't avoid exceptions
(e.g. std::bad_alloc), and you can't in general control what other
classes decide to throw. The best you can hope to do is to recover
safely. Exception-neutrality means that you will safely pass through
exceptions to the caller, which is in general what you want.
Fantastic tools for exception safety are std::auto_ptr and swap. swap
does not throw. The assignment operator should (ideally) not leave the
object in a half-copied state in the face of an exception.
e.g. Here is an exception-neutral class. If allocation fails, or any of
the constructors throw, the class performs the correct clean-up.
class C
{
std::auto_ptr<X> x;
std::auto_ptr<Y> y;
public:
C(const C &c) : x(new X(*c.x)), y(new Y(*c.y))
{
}
C& operator=(const C &c)
{
std::auto_ptr<X> new_x(new X(*c.x));
std::auto_ptr<Y> new_y(new Y(*c.y));
x.swap(new_x);
y.swap(new_y);
return *this;
}
};
[color=blue]
> Have a nice day,
> Mihai.
>[/color] | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
* Calum Grant:[color=blue]
>
> e.g. Here is an exception-neutral class. If allocation fails, or any of
> the constructors throw, the class performs the correct clean-up.
>
> class C
> {
> std::auto_ptr<X> x;
> std::auto_ptr<Y> y;
> public:
> C(const C &c) : x(new X(*c.x)), y(new Y(*c.y))
> {
> }[/color]
For others who read this, a subtle point: this works because there's a
sequence point between each pair of initializer in the initialization list.
In a an ordinary function call it's generally not safe to have more than one
'new' in the arguments. One cure is then to wrap the allocations in
functions so that the compiler cannot choose to first allocate all objects'
memory and only then call the constructors.
Btw., there should really be some way to construct a C object... ;-)
[color=blue]
> C& operator=(const C &c)
> {
> std::auto_ptr<X> new_x(new X(*c.x));
> std::auto_ptr<Y> new_y(new Y(*c.y));
> x.swap(new_x);
> y.swap(new_y);
> return *this;
> }[/color]
Typo: you meant
std::swap( x, new_x );
std::swap( y, new_y );
(std::auto_ptr has no swap member function).
[color=blue]
> };[/color]
--
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? | 
July 23rd, 2005, 05:00 AM
| | | Re: Throwing exceptions from copy constructor
"John Carson" <jcarson_n_o_sp_am_@netspace.net.au> wrote in message
news:d7n06f$2hun$1@otis.netspace.net.au[color=blue]
>
> The standard way to handle this is to wrap anything in class A that
> needs to be cleaned up in a class of its own (say, classes B, C and
> D) and then make objects of those classes (say, b, c and d) members
> of A. The initialisation of b, c and d can then occur in A's
> constructor (via the initialisation list). If, say, the
> initialisation of d causes an exception, then b and c will have been
> fully constructed (unlike the A object) and hence their destructors
> will be called, even though the A object's constructor won't be. This
> achieves the necessary cleanup.[/color]
Typo here:
"even though the A object's constructor won't be"
should be
"even though the A object's *destructor* won't be"
--
John Carson | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 220,840 network members.
|