
Passing on exceptions - vectorbunny
https://rachelbythebay.com/w/2012/09/26/exc/
======
helmut_hed
Speaking from experience, that post is a good summary of the things that come
to mind when you're used to good old-fashioned error codes and you're faced
with exceptions for the first time. There should be a FAQ with good answers to
these questions.

------
jonkalb
Let me start by addressing the GNU Radio example Rachel shared:

try { foo = new foo_bar(a, b, c, d); return foo; } catch (...) { delete foo;
return 0; }

In this snippet we don't know what the original value of foo is. At first
glance that seems to be unimportant because foo is about to get assigned. But
actually, whether or not foo is zero is the difference between just bad code
and undefined behavior.

In this example, the only thing in the try block that can throw is the
expression "new foo_bar(a, b, c, d)" Since the code behaves in the expected
way if that doesn't throw, let's only consider the case where that does throw.

Note that if a new expression throws it is the responsibility of the runtime
new operator to clean up anything that has been allocated. (There is one small
caveat here which isn't consequential.)

Also note that if the new expression throws, the value of foo is unchanged.
This means that in the case that we are considering here (the new expression
throws) the "delete foo" is deleting the original value of foo. This means
that what happens depends on that original value. There are three cases, foo
was NULL, foo pointed to an existing object, or foo was uninitialized memory.
(The case where foo points to a deleted object is really just the same as foo
being uninitialized memory.)

The cases:

 _) foo is zero. In this case "delete foo" is harmless and the only bug is
that it does nothing, can lead to confusion in readers, and should be removed.

_ ) foo points to an existing object. If we assume that this code doesn't
leak, then there is another pointer somewhere that also points to that object.
In the case we are considering (the throw case) this code is going to delete
this object (the one that foo originally pointed to, not the one that new was
trying to create--that one has already been cleaned up). This means that when
the code tries to access this object (which it will eventually, even if just
to delete it) we will invoke undefined behavior.

 _) foo is uninitialized memory. In this case we invoke undefined behavior as
soon as we attempt to "delete foo"

_ __

I think that using exceptions is _the_ way to write C++ code, but I don't
think anyone should use them until they understand the fundamentals of
exception-safe code.

I have an entire talk about why to use exceptions and how to use them safely
in C++. My site at exceptionsafecode.com has a video of both my Classic C++
talk given at last year's Silicon Valley Code Camp and my "two-parter" that
includes the C++11 information that I did for C++ Now! (BoostCon). I'm giving
the two-part talk again in a few days at this year's Silicon Valley Code Camp.

Information about Silicon Valley Code Camp (which free and in just a few days)
is here: <http://www.siliconvalley-codecamp.com>

My session is here: [http://www.siliconvalley-
codecamp.com/Sessions.aspx?SessionI...](http://www.siliconvalley-
codecamp.com/Sessions.aspx?SessionID=952)

The C++/C++11 Track that I put together is here: <http://www.siliconvalley-
codecamp.com/Sessions.aspx?track=33>

My website with videos of my talks is here: <http://exceptionsafecode.com>

And I can be contacted at "jon@" the exceptionsafecode domain.

