There're two widely used implementations of static assert for versions of C++ that don't have built-in static_assert
.
The first one is used in Boost and uses a template and a specialization of that template:
template <bool> struct static_assert;
template <> struct static_assert<true> {}; // only true is defined
#define STATIC_ASSERT(x) static_assert<(x)>()
Here once a condition to check is false the compiler is unable to find a generic version of template and compilation fails.
the second uses a typedef
:
#define STATIC_ASSERT( x ) typedef char __STATIC_ASSERT__[( x )?1:-1]
Here once a condition to check is violated the compiler attempts to typedef
an array of size -1 and that's illegal hence a compile-time error.
To me the latter is better since it is guaranteed to emit no code and also it can be used like this (from here):
template<int Shift> class BinaryFlag {
STATIC_ASSERT( 0 <= Shift && Shift < sizeof( DWORD) * CHAR_BIT );
public:
static const DWORD FlagValue = static_cast<DWORD>( 1 << Shift );
};
#define BINARY_FLAG( n ) CBinaryFlag<n>::FlagValue
while the former can't be used like that.
Is there any reason to prefer the former implementation of static assert over the latter one?