Should I throw an exception in my destructor?

The following is the work of Marshal Cline @ C++ FAQ.

 

Write a message to a log-file.  Or call Aunt Tilda.  But do not throw an exception!

Here’s why (buckle your seat-belts):

The C++ rule is that you must never throw an exception from a destructor that is being called during the “stack unwinding” process of another exception. For example, if someone says throw Foo(), the stack will be unwound so all the stack frames between the throw Foo() and the } catch (Foo e) { will get popped.  This is called stack unwinding.

During stack unwinding, all the local objects in all those stack frames are destructed.  If one of those destructors throws an exception (say it throws a Bar object), the C++ runtime system is in a no-win situation: should it ignore the Bar and end up in the } catch (Foo e) { where it was originally headed?  Should it ignore the Foo and look for a } catch (Bar e) { handler?  There is no good answer — either choice loses information.

So the C++ language guarantees that it will call terminate() at this point, and terminate() kills the process.  Bang you’re dead.

The easy way to prevent this is never throw an exception from a destructor.  But if you really want to be clever, you can say never throw an exception from a destructor while processing another exception.  But in this second case, you’re in a difficult situation: the destructor itself needs code to handle both throwing an exception and doing “something else”, and the caller has no guarantees as to what might happen when the destructor detects an error (it might throw an exception, it might do “something else”).  So the whole solution is harder to write.  So the easy thing to do is always do “something else”.  That is, never throw an exception from a destructor.

Of course the word never should be “in quotes” since there is always some situation somewhere where the rule won’t hold.  But certainly at least 99% of the time this is a good rule of thumb.

Favorite 10-Liner

shared_ptr< widget > get_widget( int id ) {

    static map< int, weak_ptr< widget > > cache;
    static mutex m;

    lock_guard< mutex > holder( m );
    auto sp = cache[ id ].lock();
    if ( !sp ) cache[ id ] = sp = load_widget( id );
    return sp;

}
// credit to Herb Sutter @ Going Native 2013

Isn’t this awesome?

No?

Well, let’s see…

  • Is this thread-safe?
  • What’s the lifetime of the objects in the cache?
  • What happens if you ask for an object not in the cache?

And so… Isn’t this awesome?

 

 

P.S. the other 3 lines:

Widget &instance() {
    static Widget w;
    return w;
}
// credit to Herb Sutter @ Going Native 2013

Who Doesn’t Want Optimization? (Part One)

When it comes to optimization, C is often regarded as the ultimate language. Simple and efficient, C encourages programmers to write customized, often lightweight, though sometimes obscure, routines as opposed to its feature-richer alternatives. But is C always better at efficiency than other mainstream alternatives?

Ever since its birth, C++ has frequently been the subject of criticism for being overly bloated and complicated. Some of its higher-level, fancier features such as virtual functions and RTTI, although nice to have otherwise, more often than not impose unwanted performance penalties. The new C++ 11 standard has introduced a slew of new features, among which many aim to improve the performance. This post is going to look at constexpr and how its uses can provide a kind of optimization that is difficult, if not impossible, to achieve in C.

Continue reading

Does Restrict Actually Improve Performance?

C99 has introduced a slew of new features into the language, among which many are aimed at improving the performance and flexibility of C in embedded programming. A prominent example would be the new keyword restrict. Its sole purpose is to enable low level optimization by the compiler. The standard states the following with regards to this keyword.

The intended use of the restrict qualifier is to promote optimization, and deleting all instances of the qualifier from all preprocessing translation units composing a conforming program does not change its meaning.

This post is to explore the various uses of restrict and attempt to answer the following questions.

What does it do? Does it actually help? Will it ever backfire? And, finally, is it worth the effort?

Continue reading

Implicit Function Declarations Will Bite

Is the following code correct in C?

#include <stdio.h>
int main () {
    int i = DoSomething();    /* does it work? */
    printf("%d\n", i);
    return 0;
}
int DoSomething (int num) {
    return 5;
}

I haven’t done any survey on this, but I dare to guess that most modern day coders would answer the above code would not compile. Reasons are obvious. DoSomething is used without being declared first and the parameter defined in the function signature is missing from the caller. At the very least, when I first saw it, I was convinced that it would not work.

However, it turns out that it is indeed legal1 C code (albeit legacy). Running it against gcc without any option produced no warning message, and executing the resulting binary did indeed produce an output of 5. This is known as the implicit function declaration rule.

So, how does this rule work? How does the compiler handle an unresolved function call? What are the pitfalls?

Continue reading