473,597 Members | 2,239 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Unexpected behavior on exception

In C# (and C++/cli) the destructor will be called even if an exception
is thrown in the constructor. IMHO, this is unexpected behavior that can
lead to an invalid system state. So beware!

http://www.geocities.com/jeff_louie/oop30.htm

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Jan 2 '06 #1
9 2177
Jeff Louie <je********@yah oo.com> wrote:
In C# (and C++/cli) the destructor will be called even if an exception
is thrown in the constructor. IMHO, this is unexpected behavior that can
lead to an invalid system state. So beware!

http://www.geocities.com/jeff_louie/oop30.htm


Why does the page say it's "non-standard" behaviour? I suspect by that
you mean "not as unmanaged C++ works" which isn't the same thing at
all. It's standard behaviour in terms of it being the behaviour the CLI
standard would suggest. (The object has been created, after all.)

--
Jon Skeet - <sk***@pobox.co m>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Jan 2 '06 #2
Hi Jon... I reworded the statement. But it is not only C++ that enforces
this idiom. Even the lowly PHP enforces this idiom. Knowing that the
destructor will only be called on a fully constructed object is integral
to the RAII idiom. IMHO it makes sense that if the _user_ defined
constructor code does not execute to completion then the _user_ defined
destructor code should not execute. This does not stop fully constructed
base objects from calling _their_ destructors. so if [[DefaultObject
alloc]init] succeeds but myObject = [[[DefaultObject alloc]init]myInit]
fails, go ahead and call the destructor of DefaultObject, but _don't_
call the destructor of myObject.

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Jan 3 '06 #3
Jeff Louie wrote:
Hi Jon... I reworded the statement. But it is not only C++ that enforces
this idiom. Even the lowly PHP enforces this idiom. Knowing that the
destructor will only be called on a fully constructed object is integral
to the RAII idiom.
I don't see that it's that integral - it's easy enough to guard against
trying to release resources twice.
IMHO it makes sense that if the _user_ defined
constructor code does not execute to completion then the _user_ defined
destructor code should not execute. This does not stop fully constructed
base objects from calling _their_ destructors. so if [[DefaultObject
alloc]init] succeeds but myObject = [[[DefaultObject alloc]init]myInit]
fails, go ahead and call the destructor of DefaultObject, but _don't_
call the destructor of myObject.


Hmm. "Partially-constructed" objects still need to be garbage
collected, however - so why would they not need to be finalized? What
if the base class constructor succeeds, but the derived class
constructor then fails - would you expect the base class finalizer to
be called, but not the derived class finalizer?

The current behaviour seems consistent to me - you don't need any
special rules about when an object is deemed to be "finalizabl e". A
"partially-constructed" object is still an object - and may indeed be
used elsewhere, if a constructor (say) adds "this" to a list of
objects, or keeps a static reference somewhere. (Yes, those are both a
bad idea - just listing possibilities :)

In both cases you have to be careful - in the C++ semantics you need to
make absolutely sure that you release any resources acquired during
construction if an exception is thrown. In the CLR semantics you need
to make sure that you don't try to release something that was never
acquired (or which has already been released). I see the latter as
easier though, as there's a single finalizer but there may be many
constructors. Better to only have to be careful in one place :)

Jon

Jan 3 '06 #4

"Jeff Louie" <je********@yah oo.com> wrote in message
news:%2******** ********@TK2MSF TNGP11.phx.gbl. ..
Hi Jon... I reworded the statement. But it is not only C++ that enforces
this idiom. Even the lowly PHP enforces this idiom. Knowing that the
destructor will only be called on a fully constructed object is integral
to the RAII idiom. IMHO it makes sense that if the _user_ defined
constructor code does not execute to completion then the _user_ defined
destructor code should not execute. This does not stop fully constructed
base objects from calling _their_ destructors. so if [[DefaultObject
alloc]init] succeeds but myObject = [[[DefaultObject alloc]init]myInit]
fails, go ahead and call the destructor of DefaultObject, but _don't_
call the destructor of myObject.

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***


If an exception propagates out of a constructor, you'll have to make sure
that your destructor (Finalize) can handle "partially contructed" objects.
Another option is to catch exceptions in the contructor and suppress
finalization, like:

class Foo {
public Foo()
{
try {
FunctionThatCan Throw();
}
catch(Exception ) {
GC.SuppressFina lize(this);
throw;
}
resourceHandle = ....// allocate unmanaged resource that needs
clean-up.
}
~Foo()
{
if(resourceHand le)
... // clean-up
}

Willy.

Jan 3 '06 #5
In addition to the comments and options Jon and Willy offered, you can also
separate the construction of the object from the acquisition of resources
into two separate phases so that the constructor never throws an exception.
In the constructor set fields to known values (null, etc) to estiablish its
invariants, then use an Initialization method to acquire the resources.

FYI: If an exception is thrown from a static constructor then that type is
thereafter unusable in that appdomain - you will not be able to create
instances of that type in that AppDomain.

"Jeff Louie" <je********@yah oo.com> wrote in message
news:%2******** ********@TK2MSF TNGP11.phx.gbl. ..
Hi Jon... I reworded the statement. But it is not only C++ that enforces
this idiom. Even the lowly PHP enforces this idiom. Knowing that the
destructor will only be called on a fully constructed object is integral
to the RAII idiom. IMHO it makes sense that if the _user_ defined
constructor code does not execute to completion then the _user_ defined
destructor code should not execute. This does not stop fully constructed
base objects from calling _their_ destructors. so if [[DefaultObject
alloc]init] succeeds but myObject = [[[DefaultObject alloc]init]myInit]
fails, go ahead and call the destructor of DefaultObject, but _don't_
call the destructor of myObject.

Regards,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***

Jan 4 '06 #6
Willy and MSFT... I added your suggestions to the article.

Thanks,
Jeff

*** Sent via Developersdex http://www.developersdex.com ***
Jan 8 '06 #7
On Sun, 01 Jan 2006 19:32:15 -0800, Jeff Louie <je********@yah oo.com>
wrote:
In C# (and C++/cli) the destructor will be called even if an exception
is thrown in the constructor. IMHO, this is unexpected behavior that can
lead to an invalid system state. So beware!


Unexpected to you perhaps. I can't see anything else happening as
preferable. If an object gets half way through construction and
fails for /any/ reason, I would certainly want the destructor called
to clean up any partially constructed stuff and release any partially
aquired resources.

Oz
--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jan 8 '06 #8
Hello ozbear,
Unexpected to you perhaps. I can't see anything else happening as
preferable. If an object gets half way through construction and fails
for /any/ reason, I would certainly want the destructor called to
clean up any partially constructed stuff and release any partially
aquired resources.


I agree. It can be quite awkward at first but taken the other way you would
have to implement a destructor twice. Once in the destructor and once in
the constructor to handle any un-expected errors.

--
Jared Parsons
ja****@beanseed .org
http://jaredparsons.blogspot.com
Jan 8 '06 #9
Ozbear... It's not that simple. First, say a reference counter is
incremented in
the constructor. In standard C++ I know that the destructor will only be
called if the constructor completes successfully so that I know that I
can
decrement the reference count in the destructor. Period. In C# there is
no
such guarantee. I need to code around this. If I don't, I could
decrement the
reference counter in the destructor and another object can try to call a
method on a prematurely released resource.

Secondly, there is _no_ guarantee that the destructor will be called in
a timely
manner! If an exception is thrown in the constructor in a using
construct,
Dispose is _not_ called. The resource will only be released when the
garbage
collector gets around to it.

So IMHO, cleaning up the resources in the constructor on exception and
then
call GC.SuppressFina lize(this) is the preferable solution for
deterministic
release of unmanaged resources.

Regards,
Jeff
Unexpected to you perhaps. I can't see anything else happening as

preferable. If an object gets half way through construction and
fails for /any/ reason, I would certainly want the destructor called
to clean up any partially constructed stuff and release any partially
aquired resources.<

*** Sent via Developersdex http://www.developersdex.com ***
Jan 9 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
4236
by: Robert Mazur | last post by:
MySQL 5.0 alpha (binary install) on Solaris 9 -or- RedHat 8.0 mysql-connector-java-3.0.8-stable ----------------------- Is there something different going on with JDBC and the alpha version of MySQL 5.0? When trying to connect I am getting: ** BEGIN NESTED EXCEPTION **
2
10432
by: Attila Feher | last post by:
Hi all, I have not done much work around exceptions; and even when I do I avoid exception specifications. But now I have to teach people about these language facilities, so I am trying them out with gcc 3.4.2-mingw. I have tried the TCPL Spec.Ed. example of just adding std::bad_exception to the exception specification of a function promising to throw an int, but throwing a string-literal (effectively a pointer). I call that from main...
3
2850
by: Teddy | last post by:
Hello all According to "Think in C++ Volume2", the code below should run smoothly: #include <iostream> #include <exception> using namespace std; class ex { };
6
5970
by: Samuel M. Smith | last post by:
I have been playing around with a subclass of dict wrt a recipe for setting dict items using attribute syntax. The dict class has some read only attributes that generate an exception if I try to assign a value to them. I wanted to trap for this exception in a subclass using super but it doesn't happen. I have read Guido's tutorial on new style classes and Shalabh's tuturial on new style attributes and methods, and thought I understood...
3
4064
by: Rahul Anand | last post by:
As per our requirements we have a web service which internally connects (Simple HTTP Post Request) to a remote server to initiate some work. We are calling the web service method asynchronously from a .NET Web Application hosted on IIS. In our setup the web request form a client can be running for long duration (may be more than 4 hours). We are getting exceptions during the HTTP send/receive inside the web service method. The exception...
2
3452
by: bb | last post by:
Hi, I am using gcc v4.0.2 on fedora core 4 (2.6.16). Any reason why the handler set thru' set_unexpected() never gets called in the following code? --------- Code ------------- #include <iostream> #include <exception> #include <string>
0
1571
by: Mahesh Devjibhai Dhola | last post by:
Hi, I am getting the following exception when using webservice.. "The underlying connection was closed: An unexpected error occurred on a receive" I am not getting any innerexception so no clue for the reason. While i was seaching on web, i found the solutions but its not working for me. I have already override the method on client proxy but its not working, protected override System.Net.WebRequest GetWebRequest(Uri uri) {
3
3305
by: Anup Daware | last post by:
Hi Group, I am facing a strange problem here: I am trying to read xml response from a servlet using XmlTextWriter. I am able to read the read half of the xml and suddenly an exception: “Unexpected end of file while parsing Name has occurred” isbeing thrown. Following is the part o xml I am trying to read: <CHECK_ITEM_OUT>
2
1700
by: mbeachy | last post by:
Some rather unexpected behavior in the set_default/set_defaults methods for OptionParser that I noticed recently: <Option at 0x-483b3414: -r/--restart> {'restart': None} {'retart': False, 'restart': None} Why does set_default not raise an exception when passed a key that it doesn't recognize?
0
7969
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main usage, and What is the difference between ONU and Router. Lets take a closer look ! Part I. Meaning of...
0
7886
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8272
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
6688
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
5847
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5431
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
3927
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1494
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1238
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.