Tuesday, December 2, 2008

Compile-time assertions

The new C++0x standard contains a neat feature called static_assert which does a compile-time assertion. It's really useful in cases we can't use the #if keyword (preprocessor) to throw a compile-time error. This happens when the preprocessor finds a C construct or expression it can't resolve such as sizeof, even if it is known at compile-time (actually it's only known to the compiler).

After searching the web I found this webpage that contains a nice trick to do this assertions in C. However, the macros defined there do not provide a description about the assertion, which might be useful, so here is my modified version:


/**
* STATIC ASSERT
* -- based on
* http://www.pixelbeat.org/programming/gcc/static_assert.html
*/
#define ASSERT_CONCAT_(a, b, c) a##b##c
#define ASSERT_CONCAT(a, b, c) ASSERT_CONCAT_(a, b, c)
#define STATIC_ASSERT(e,descr) enum { ASSERT_CONCAT(descr,_Line_,__LINE__) = 1/(!!(e)) }

As an example, this would require the size of the struct myStruct to be less than 20 in order to compile (this is only an example, remember 'magic numbers' should be avoided when programming):



STATIC_ASSERT( sizeof( struct myStruct ) < 20, MyStructIsTooLarge );

If there is an assertion error at compile time this error will be thrown:



file.c:40: error: division by zero
file.c:40: error: enumerator value for 'MyStructIsTooLarge_Line_40' is not an integer constant

On the other side, if C++ is being used and there is access to a (at least partial) C++0x compiler you can use static_assert() in a similar way:



static_assert( sizeof( struct myStruct ) < 20, "My Struct Is Too Large" );


Currently GCC 4.3 supports static_asserts as mentioned here.

No comments:

Post a Comment