Skip to main content

destructors and exceptions

This is a small part of the discussion going on writing exception safe code in C++ especially for large C++ programs such as ACE/TAO library/frameworks. This snippet is extracted from tens of emails on the topic on the devo-group mailing list of DOC (Distributed Object Computing) group. A major part of this reply was given by Carlos O'Ryan, former student of Dr. Doug Schmidt, a famous CORBA expert.

>> Either use C++ exceptions to propagate errors from constructors

I agree with that.

>> or don't do anything in constructors that can fail and put all such
>> activities in an open() method.


Unfortunately that does not jive well with RAII, a very important C++
idiom.


>> "Swallow errors in destructors".
>>


This is something I always feel queasy about. Yes, I understand why
destructors should not fail (which is a stronger requirement than not
raising exceptions.) However, destructors can and will fail when
dealing with OS resources (or even worse, distributed resources.) What
is one to do?

I think it is a case where a blanket statement is inappropriate. The
developer must choose between equally bad alternatives, and pick the
right one in the context. We all understand that it is impossible to
provide the strong exception guarantee (or the weak one for that matter)
if some destructors can fail. However, in long running systems, errors
can and do happen. At the very least one should provide enough logging
for post-mortem analysis. If you blindly swallow the errors in the
destructor your application will not be supportable in the field. If
you let the exceptions propagate then you cannot offer the strong
exception guarantee. Logging the problems is tempting, but logging is
not always available or appropriate (what if the error was detected
while disconnecting from your logging service or closing the logging
file?)

One should remember why the exception guarantees are desirable. They
simplify the analysis of the program. It is easier to convince oneself
that the system will remain in a consistent state if the transitions
either succeed or fail. One can, however, perform more detailed
analysis when an exception is raised and still argue that the system is
safe.

The trick is for libraries like ACE or TAO. In such libraries it is
impossible to know what the right action is, because it depends on the
context. I would suggest that using hooks is the only viable
alternative in such cases.

Comments

Anonymous said…
What do you mean by "strong exception guarantee"?
Prodigious blog. Loved it so much I went to it
again! Just go online and search for blogs that are
worth the value as yours.
Stop by and visiit my cash advance pittsburgh blog!
Fine blog. I found your site suitable for another
visit! And when I'm able to surf the web, I look for
blogs as great as your work.
You got me! I will check out your coupon codes 1800contacts blog a.s.a.p!
dat-girl said…
Astonshing blog. I relished in the site and you
know I will be going to it again! Surfing the internet
hepls me to find blogs that arfe just as good.
Go and click my 1800contacts coupon blog.
Delightful blog. I devote my spare time just
looking for great blogs such as yours. I treasure this
site and will go back!
If your look to uncover information, please visit my 1800contacts web coupon code blog
Delightful blog. I devote my spare time just
looking for great blogs such as yours. I treasure this
site and will go back!
I was in love with your blog site.
Exciting blog. Your site was amazing and will be
back again! I never get tired of looking for blogs
just like this one.
Check out my blog, please!
after-while said…
Fine blog. I found your site suitable for another
visit! And when I'm able to surf the web, I look for
blogs as great as your work.
Go by and hit my blog, you'll be glad you did.
condensed said…
Creative blog. I just kept looking at it over and
over! Im always looking for blogs like this!
I wish I was like you, but I'll go and peep your 1800contacts coupon blog.
Incredible blog. I admired your site and I will be
back once again to view it! I use much of my spare
time searching for blogs like yours.
Jump into my breast plastic surgery blog.
Sensational blog. I took pleasure in the site and I
will go back! Surfing online for blogs like this one
is worth my time.
Jump into my cosmetic plastic surgery blog.
manho valentine said…
Exciting blog. Your site was amazing and will be
back again! I never get tired of looking for blogs
just like this one.
Check out my blog, please!
thanks you!
gclub

Popular posts from this blog

Multi-dimensional arrays in C++11

What new can be said about multi-dimensional arrays in C++? As it turns out, quite a bit! With the advent of C++11, we get new standard library class std::array. We also get new language features, such as template aliases and variadic templates. So I'll talk about interesting ways in which they come together.

It all started with a simple question of how to define a multi-dimensional std::array. It is a great example of deceptively simple things. Are the following the two arrays identical except that one is native and the other one is std::array?

int native[3][4];
std::array<std::array<int, 3>, 4> arr;

No! They are not. In fact, arr is more like an int[4][3]. Note the difference in the array subscripts. The native array is an array of 3 elements where every element is itself an array of 4 integers. 3 rows and 4 columns. If you want a std::array with the same layout, what you really need is:

std::array<std::array<int, 4>, 3> arr;

That's quite annoying for two r…

Understanding Fold Expressions

C++17 has an interesting new feature called fold expressions. Fold expressions offer a compact syntax to apply a binary operation to the elements of a parameter pack. Here’s an example. template <typename... Args> auto addall(Args... args) { return (... + args); } addall(1,2,3,4,5); // returns 15. This particular example is a unary left fold. It's equivalent to ((((1+2)+3)+4)+5). It reduces/folds the parameter pack of integers into a single integer by applying the binary operator successively. It's unary because it does not explicitly specify an init (a.k.a. identity) argument. So, let add it. template <typename... Args> auto addall(Args... args) { return (0 + ... + args); } addall(1,2,3,4,5); // returns 15. This version of addall is a binary left fold. The init argument is 0 and it's redundant (in this case). That's because this fold expression is equivalent to (((((0+1)+2)+3)+4)+5). Explicit identity elements will come in handy a little la…

Folding Monadic Functions

In the previous two blog posts (Understanding Fold Expressions and Folding Functions) we looked at the basic usage of C++17 fold expressions and how simple functions can be folded to create a composite one. We’ll continue our stride and see how "embellished" functions may be composed in fold expressions.

First, let me define what I mean by embellished functions. Instead of just returning a simple value, these functions are going to return a generic container of the desired value. The choice of container is very broad but not arbitrary. There are some constraints on the container and once you select a generic container, all functions must return values of the same container. Let's begin with std::vector.
// Hide the allocator template argument of std::vector. // It causes problems and is irrelevant here. template <class T> struct Vector : std::vector<T> {}; struct Continent { }; struct Country { }; struct State { }; struct City { }; auto get_countries…