I agree that exceptions from C++ constructors can be dangerous, although you
can dealing with them safely if you're careful. Yes this is fine in .NET.
However, exceptions from C++ destructors are always dangerous, and this is
still true in .NET.

In C++, if an exception can escape a destructor, it means it could get
thrown while doing the stack-unwind due to processing another exception.
Since you can't propagate two exceptions at the same time, std::terminate()
is called (not sure what the default behaviour under Visual C++ is, probably
kill the process).  Bjarne Stroustrup (creator of C++) describes this as "a
failure of the exception handling mechanism".

In .NET if you throw an exception from a finalizer, it's just treated as an
unhandled exception and shouldn't be problem any more than any other
unhandled exception (i.e. it does not terminate the finalizer thread, future
finalizations still happen).

But the closest thing to C++ destructors in .NET aren't really finalize
methods (which you want to avoid as much as possible), it's Dispose methods
(which you should use whenever you need cleanup).  Throwing an exception
from a Dispose method leads to the same problem as in C++: which exception
should be propagated?  Instead of taking the idealist approach of C++ ("this
is a serious failure, can't reasonably choose"), .NET takes a perhaps more
intuitive choice: if exception B is thrown from a finally block while
unwinding the stack for exception A  (eg. from a Dispose call due to a
'using' statement), just throw away all the information about exception A
and instead propagate exception B.  (Surprisingly, I couldn't find this
behaviour mentioned explicitly in the CLI spec, am I just missing it?).

In my opinion, the .NET behaviour is almost worse than the C++ behaviour.  I
have seen many situations where a rare bug gets triggered, and the exception
details are thrown away and replaced with a new exception generated inside a
finally block.  So all I get in my logs are the details of the 2nd exception
, not the 1st one that actually caused the problem.  Of course the solution
is to prevent throwing exceptions from my finally blocks, but this can be
very hard to guarantee, and you generally won't discover a problem until
you've lost information about a more important bug that needs to be tracked
down.  I kind of wish that any exception thrown from a finally block was
treated as unhandled and didn't interrupt the processing of the original
exception.

Rick

----- Original Message -----
From: "Chris Snyder" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Wednesday, March 31, 2004 9:29 AM
Subject: Exceptions in Constructors


> I have a (hopefully) simple question.
>
> In a nutshell, as a C++ developer, various people hammered into my brain
> that throwing an exception in a constructor (whether intentionally or by
> performing some action which would cause an exception to be thrown) was
> extremely bad. However, my research seems to indicate that .NET handles
> constructors differently, allowing developers to perform actions in a
> constructor that may result in exceptions being thrown, or to <gasp> even
> throw an exception themselves.
>
> Thoughts?
>
> Thanks a lot,
> Chris Snyder
>
> ===================================
> This list is hosted by DevelopMentorŪ  http://www.develop.com
> Some .NET courses you may be interested in:
>
> NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
> http://www.develop.com/courses/gaspdotnetls
>
> View archives and manage your subscription(s) at
http://discuss.develop.com
>

===================================
This list is hosted by DevelopMentorŪ  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to