[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.