The final macro

The problem

Cleaning up resources is hard. One has to keep track of all allocated resources and make sure to free each one on each error path. The difficulty is compounded, some say, with exceptions, which can make error paths non-obvious. Traditionally, C++ programmers use RAII wrappers (e.g. unique_ptr
and CComPtr) to automatically clean up resources --- but it's inconvenient to create a new type for each possible cleanup activity. In exceptional code in particular, we're often forced to either create yet another RAII type, or duplicate cleanup code in the success and exception-rethrowing paths. It becomes messy quickly.

The solution

Other languages provide facilities (like finally and unwind-protect) to delay the execution of bits of code until the current task is completed; it's natural to clean up resources in finally blocks. C++ has never had finally blocks, but the latest language features allow us to create them ourselves. I've always said that the wondering thing about C++ is its ability to create very powerful, but also easy-to-use abstractions. It's powerful enough to implement features other languages have to have built in. Let's look at an example:

Code Output
foo (int n)
    printf ("foo %d\n", n);

bar ()
    int* x = new int (5);
    FINALLY (foo (*x), delete x);

    printf ("Hello, world!\n");

    FINALLY ({
        if (x) {
            printf ("Look, a statement!\n");

    printf ("Second line\n");

qux ()
    FINALLY (printf ("After throw\n"));
    printf ("throwing\n");
    throw 42;

int main ()
    bar ();
    printf ("bar returned\n");
    try {
        qux ();
    } catch (int) {
        printf ("caught exception\n");
    printf ("qux returned\n");
Hello, world!
Second line
Look, a statement!
foo 5
bar returned
After throw
caught exception
qux returned

The code above isn't witchcraft. It's standards-conforming† code. Here's the bit that makes it work:

#include <utility>

template<typename FunctorT>
struct FinallyUnwinder
    FinallyUnwinder (FunctorT Functor)
        : Functor (std::move (Functor))

    FinallyUnwinder (FinallyUnwinder&& Other)
        : Functor (std::move (Other.Functor))

    ~FinallyUnwinder ()
    { this->Functor (); }
    FinallyUnwinder (const FinallyUnwinder& other);
    FinallyUnwinder& operator=(const FinallyUnwinder& other);
    FunctorT Functor;

template<typename FunctorT>
typename FinallyUnwinder<FunctorT>
Finally (FunctorT Functor)
    return FinallyUnwinder<FunctorT> (std::move (Functor));

#define UTX_CAT2(a,b) a ## b
#define UTX_CAT(a,b) UTX_CAT2 (a, b)
#define UTX_GENSYM(ar) UTX_CAT (ar, __LINE__)

#define FINALLY(...)                          \
    auto UTX_GENSYM (utx_finally) =           \
        Finally ([&] () { __VA_ARGS__ ; });

This code relies on variadic macros, lambda functions, and move constructors, all of which are very recent features.

To see how it all fits together, let's look at the preprocessed version of one of the lines above:

auto utx_finally65 = Finally ([&] () { printf ("After throw\n") ; });;

Here, we're creating a lambda functor object, capturing all variables from the parent function by their addresses (which is fine, because this lambda will never run after its parent function returns), and stashing the result away in an automatic variable; its type is specific to the functor being assigned, and its name is created via macro magic. The compiler understands what's going on and can inline this entire process, producing code that's just as efficient as the hand-coded equivalent.


Using powerful primitives built into C++, we can create new expressive constructs, and we don't need to give up any performance in the process. The above macro, while tricky to implement, is an convenient alternative to explicit RAII. While previous attempts to enjoyed some success, it's only with C++11 that we're able to provide a natural and convenient syntax.


† - variadic macros are technically supported in C99, not C++, but support for variadic macros in C++11 compilers is universal.

Comments (9)

  1. Benjamin Bannier says:

    Boost.ScopeExit does exactly that, so why should I implement this myself?

  2. dancol says:

    Because FINALLY (foo (bar)) is cleaner than BOOST_SCOPE_EXIT ((&bar)) { foo(bar); } BOOST_SCOPE_EXIT_END

  3. John says:

    If you're using finally in C++, YOU ARE DOING IT WRONG.

  4. peterchen says:

    Andrei & Petru, December 2000:

  5. John Haugeland says:

    This makes me die a little inside.  It's like you don't know that C++ exceptions aren't for error handling.  This language is not Java, sir.

  6. dancol says:

    C++ exceptions _are_ for error handling. That's the point.

  7. V says:

    @John Haugeland, if exceptions aren't for error handling, then what do you recommend doing when a constructor fails ?

  8. Brooks Moses says:

    Of course, this does have a flaw; the following will fail to compile with a weird error:

    void this() {

     FINALLY(that()); FINALLY(the other());


    because the two FINALLY statements are on the same line.  It's unfortunate that there's not a better way of creating almost-always-unique names in macros than using the line number.

  9. witek says:

    In D language there is greate way of doing cleanup using scope(exit/failure/success), blocks. It works regardles how you exit (return, jump, exception, error). Makes life so much easier.

Skip to main content