Feb 23

The fail fast idiom is all about catching software errors at the earliest possible stage. The idiom is surprisingly often just neglected, as if developers loved to spend days tracking down obscure bugs which they know would just as well have been caught with a tiny bit of extra work in the first place.

Failing fast doesn’t mean that the number of failures increases. Rather, it means that the failures are not neglected and ignored, but found as soon as possible. For example, suppose that we call a function that returns a value, which in our subsequent code must then be below a certain maximum value:

int value = p->FunctionCall();
if ( value > max )
{
    value = max;
}

DoStuff( value );

Here, if the returned value is greater than max, it is set to max. DoStuff() requires that the value is less or equal to max. Now, this clamping may or may not be the intended behaviour. If setting the value to max is just a fail-safe in order to prevent DoStuff() from crashing if p->FunctionCall() returns an erroneous value, it is better to make sure already at this point that the value is indeed within specified bounds by adding an assertion.

Assertions are one of the foresighted developer’s best friends. There are a multitude of ways in which assertions are used, for example in Symbian code there are e.g. __ASSERT_DEBUG() and __ASSERT_ALWAYS() macros, for which you can provide a function to be called if the assertion fails. Then there’s the good old assert() macro from the standard C library, which is defined to write to the standard error output (prior to calling abort()) at least the asserted expression and the file name and line number where the assertion failed.

Where to put assertions, then? Usually there are quite a few places in code where a certain invariant must hold true. For example, there may be a member variable which must have a certain value upon function invocation, or else the results of the function are undefined. As a pseudocode example, imagine that we’re supposed to sell toys, and all their bells and whistles must be painted before they’re ready for shipment.

void Toy::Paint()
{
    for_each( bells_.begin(), bells_.end(), PaintFunc );
    for_each( whistles_.begin(), whistles_.end(), PaintFunc );
}

Let’s say that we add a new Toy to a vector container to be shipped to a retailer but forget to call its Paint() function. We now have a bunch of toys but, unbeknownst to us due to our negligence, one of them is missing paint from its bells and whistles. Uh oh, the delivery truck is here, and those guys don’t have all day. Better call the Offload() function to make some space in the warehouse:

void WareHouse::Offload( const std::vector<Toy>& toys )
{
    for_each( toys.begin(); toys.end(); ShipFunc );
}

Now we’re done with the toys, but one has slipped through without all the invariants checked. A good solution here would be to check in the Offload() function that we’re shipping out kosher items. Supposing that bells and whistles derive from a common class, Part, and that the base class contains a IsPainted() function to check if the part in question has been painted, we can add an assert to the Offload() function as follows:

void WareHouse::Offload( const std::vector<Toy>& toys )
{
    for ( std::vector<Toy>::const_iterator<Toy> iter = toys.begin();
           iter != toys.end(); ++iter )
    {
        assert( iter->IsPainted() );
    }

    for_each( toys.begin(); toys.end(); ShipFunc );
}

Here the assert will stop program execution to prevent shipping of unpainted toys. What we’re trying to achieve here is that already during development phase we are able to deal with code paths that result in unpainted toys being shipped. It’s better to make the problems manifest themselves as early as possible (to fail fast) than trying to find obscure bugs during the final, often hectic stages of an imminent release.

Feb 23

Consider the following class:

class Gadget
{
public:
    void MakeNewWidget()
    {
        delete widget_;
        widget_ = NULL;
        widget_ = new Widget;
    }

    const Widget& Get() { return *widget_; }

private:
    Widget* widget_;
};

In the MakeNewWidget() function the widget_ class member is first deleted and set to NULL before creating a new Widget object and assigning it to widget_. Plain and simple, and you see a lot of this kind of code around.

There’s a particular reasoning for this kind of code, especially in memory-contrived environments. The aim here is to prevent having a temporary Widget object in memory in addition to the widget_ member, thus saving on memory consumption.

But there’s something horribly wrong here. The “aim” of the code may be accurate, but it’s aiming straight at the coder’s foot. What would happen if the widget_ = new Widget; line threw an exception? The answer is that the Gadget object would be left in an inconsistent state, because the original widget_ member has already been deleted. If there’s a catch somewhere nearby down the call stack, the code there may well assume that the old state of the Gadget object is still valid; i.e. there’s been no change to its internals even though there was an exception.

We are able to remedy the situation by creating new Widget object into a temporary variable, deleting the original widget_ and assigning the temporary variable to widget_. Like follows:

void MakeNewWidget()
{
    Widget* temp = new Widget;
    delete widget_;
    widget = NULL;
}

Temporary variables such as these may not always be aesthetically pleasing, and we are using twice the amount of memory by briefly having two Widget objects present, but this code is significantly safer for the callers. No longer do the callers have to worry about the state of the Gadget object in case MakeNewWidget throws an exception, which is as it should be.

preload preload preload