[c++] Static assertions – Part II

Following on from the very quick introduction to static assertions we can now look at how they are actually implemented. Well… how they are currently implemented before C++0x comes along and cleans it all up.

Nicest way to roll your own static assertion is to use C++ templates:

template <bool B>
struct StaticAssertion;

template <>
struct StaticAssertion<true> { };

#define STATIC_ASSERT( x ) StaticAssertion<x>( )

First we forward declare a class template. Then specialise it for the true case. Finally adding a preprocessor macro to tidy up the end user syntax. As we haven’t defined the false case, the compiler will issue an error if it ever tries to instantiate it.

int main( ) {
    STATIC_ASSERT( false );
   
    return 0;
}

Visual Studio 2008 outputs:

1>main.cpp(11) : error C2514: 'StaticAssertion<B>' : class has no constructors
1>        with
1>        [
1>            B=false
1>        ]

GCC v4.0.1:

main.cpp: In function 'int main()':
main.cpp:11: error: invalid use of undefined type 'struct StaticAssertion<false>'
main.cpp:3: error: declaration of 'struct StaticAssertion<false>'

Both error messages contain the StaticAssertion type and give you the correct line the violation occurred on. From this you can deduce that a static assertion has occurred. Further improvements could be made by the use of additional type parameters to let you know the flavour of the assertion. Which is an exercise left for the reader 😉

Fortunately static assertions are not limited to C++. You can accomplish the same result using straight C.

#define STATIC_ASSERT( x ) sizeof( char[ (x) ? 1 : -1 ] )

This one liner relies on the fact that you can’t declare a negatively sized array.

Visual Studio 2008:

1>main.cpp(11) : error C2148: total size of array must not exceed 0x7fffffff bytes
1>main.cpp(11) : error C2148: total size of array must not exceed 0x7fffffff bytes
1>main.cpp(11) : error C2070: 'char [-1]': illegal sizeof operand

GCC v4.0.1:

main.cpp: In function 'int main()':
main.cpp:11: error: size of array is negative

Error messages still indicate the offending line, but that’s about it. Not as nice as the C++ templated version but the end result is the same. Program fails to compile.

[c++] Static assertions

An assertion statement is used at runtime to verify that an assumption holds true. Typically assert is only used in debug builds, while release builds switch it out completely.

Keep in mind that while an assertion is no substitute for proper error checking, it is useful for a quick verification of low level assumptions. If you design a function with the expectation that the provided pointer will always be valid; then adding an assert will warn the caller when they aren’t playing by the same rules that you are.

int get_nth_char( const char* str, int idx ) {
    assert( str ); // program stops here if str is invalid
    if ( idx < 0 ) return -1;
    return str[ idx ];
}

Static assertions take assert a step further and provide sanity checks at compile time. While static assertions can only operate on known compile time data it is still really useful. A good example is the packing of network data where it is vital that the data is packed correctly and is of the right size. Not only will a static assert verify this. It will also catch the case if it gets changed at a later stage.

#pragma pack( push, 1 )
struct PktData {
    char b1;
    char b2;
};
#pragma pack( pop )

BOOST_STATIC_ASSERT( 2 == sizeof(PktData) );

While the static assert in the above code is courtesy of boost, the upcoming C++0x standard will also include this functionality.

Autumn in Christchurch

Last weekend I flew down to Christchurch for a wedding. It was somewhat of a last minute decision, but seeing as I haven’t seen my south island relatives for several years it was well worth the effort. Fortunately domestic airlines are kind to procrastinators such as myself, so picking up a same day ticket was easy (and cheap!).

Christchurch Cathedral in Cathedral Square
The Cathedral in Cathedral square


Autumn tree in Hagley Park, Christchurch
An autumn tree in Hagley Park

Christchurch is the largest of the south island cities in New Zealand, and is located about half way down the east coast. For more information see Wikipedia.

USB orientation

Like most people I used to get the orientation of the USB connector and the port wrong. However, once you finally notice that the USB symbol is always on the top of the connector things get easier. Better yet, this is actually stated in the USB mechanical specification (emphasis added):

6.5.1 USB Icon Location
The USB Icon is embossed, in a recessed area, on the topside of the USB plug. This provides easy user recognition and facilitates alignment during the mating process. The USB Icon and Manufacturer’s logo should not project beyond the overmold surface. The USB Icon is required, while the Manufacturer’s logo is recommended, for both Series “A” and “B” plug assemblies. The USB Icon is also located adjacent to each receptacle. Receptacles should be oriented to allow the Icon on the plug to be visible during the mating process.

So as long as you can see the USB Icon, it should fit first time.

Boost v1.35.0 is out

Boost has released v1.35.0 of their C++ libraries. This includes many great goodies such as asio (asynchronous networking library), bimap (indexable by both the key and value), circular buffer, interprocess (shared memory access), and more.

“Boost provides free peer-reviewed portable C++ source libraries”

http://boost.org

If you’re going to make a better mouse trap, make sure it catches mice

My parents house is covered in picture frames, so for for christmas I got my dad one of those digital ones. At least that way they can reclaim some of their wallspace. Anyway before giving it to him I got the chance to load it with some images and have a bit of a play. While not disappointed I was surprised at some of the basic stuff the manufacturer got wrong. So here’s a couple of tips for you digital picture/photo frame designers:

Aesthetic look

Picture frames shouldn’t detract from the picture. They act as border and help focus the viewers attention perhaps even adding depth to an overall image. A corporate logo emblazed across the bottom of your frame does not meet any of these goals.

Functionality

Picture frames primary function is to display pictures. That’s what they were designed to do. Calling your product a digital picture frame and then failing to actually display pictures when you turn it on is crazy. In this particular case you are instead greeted with a menu where you have to select you want to look at photos off of this USB key.

Oh and why do most of them have speakers?!?

Magnifier

Recently I’ve been doing alot of custom drawing and graphic manipulation. Having been frustrated with other on screen magnifiers I finally went about creating my own solution.

Magnifier

  • Left mouse drag panning
  • Right mouse drag area selection
  • Quick scroll wheel zoom in/out
  • Rough rulers (which you can turn off)
  • RGB pixel value reporting

Magnifier is available from the programs section.

London underground

Coming from a country1 whose entire concept of public transportion is buses, the London underground is amazing. In most cases stations are within walking distance of one another and you can just grab a train from wherever you are, to wherever you need to go. After a while it was like playing monopoly; travelling from Leicester Square to Kings Cross station…

London Underground
London Underground

Don’t mind my attempts at being artistic. This first shot is completely unedited with the blur curtosy of a long exposure, low light, and being in a rush.

West Brompton Station - London - UK
West Brompton Station

Meanwhile this second shot has undergone a crop, some cloning to remove unwanted intruders, and an overall soften portrait effect. All curtosy of Paint.NET.

1. That would be NZ, although the San Jose area didn’t appear to be any better.