C++ Operator Overloading

| No Comments

I came across this code recently:

level = kIOStorageAccessNone;
while ( ( object = objects->getNextObject( ) ) )
{
    if ( object != client )
    {
        level += _openClients->getObject( ( OSSymbol * ) object );
    }
}

Basically, it’s going through a list of clients that it services and works out what the aggregate access level is for all the clients. Here are the possible access levels:

enum
{
    kIOStorageAccessNone          = 0x00,
    kIOStorageAccessReader        = 0x01,
    kIOStorageAccessReaderWriter  = 0x03,
    kIOStorageAccessSharedLock    = 0x04,
    kIOStorageAccessExclusiveLock = 0x08
};

Now, from looking at this code, it looks wrong because of the use of the +=. Surely |= is more appropriate. It’s obvious to me now, but it took me some time before I found the bit where they’d overridden the += operator:

inline void operator+=( IOStorageAccess access )
{
    _access = ( ( _access - 1 ) >> 1 ) & 7;
    _access = gIOMediaAccessTable[ ( ( access - 1 ) >> 1 ) & 7 ][ _access ];
    _access = ( ( _access & 7 ) << 1 ) + 1;
}

Anyway, this, in my opinion, is a classic example of an abuse of C++ operator overloading. The rule when writing code should be to make it as readable and as obvious as possible first before you start trying to be clever. If the code had been something like this:

    clientLevel = _openClients->getObject( ( OSSymbol * ) object )->unsigned32BitValue( );
    level = aggregateLevel( level, clientLevel );

it wouldn’t have cost me any time as it would have been clear what was going on.

It’s for similar reasons that I always put brackets round expressions that combine && and || clauses: not everybody knows the order of precedence of these two and it’s easy to forget; adding brackets means you don’t need to remember.

For example, I would always do:

    if ((a && b) || (c && d))

rather than

    if (a && b || c && d)

I know it’s tempting to use that clever bit of the language that you just learnt about but in doing so you might make it harder for the person that follows you. The general rule should be: unless it is a common idiom, make it clear what’s going on and if a better known alternative exists, use that instead.

Leave a comment