I want to compile on a compiler which has no static_assert implemented. So I want these lines to become no-op.
Why not combining Lundin's answer (checking whether the current compiler has it implemented or not) with an implementation of static_assert
(which is not hard to do)?
Copying the implementation from PDCLib (which is CC0 licensed):
/* with dodgy implementations, you could also #ifndef static_assert */
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112
#define _PDCLIB_cc( x, y ) x ## y
#define _PDCLIB_concat( x, y ) _PDCLIB_cc( x, y )
#define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
#endif
For a given expression e
and message m, this declares an anonymous enumeration with one member, the name of which is _PDCLIB_assert_
concatenated with the current source file line (__LINE__
) (so you can have multiple static_assert()
per source file). This member is set to 1
divided by 1
if the expression e
is true, or divided by 0
if the expression is false, which leads to output like this for a failed assert:
./path/to/source.c:57:94: warning: division by zero [-Wdiv-by-zero]
#define static_assert( e, m ) enum { _PDCLIB_concat( _PDCLIB_assert_, __LINE__ ) = 1 / ( !!(e) ) }
^
./path/to/header.h:571:1: note: in expansion of macro 'static_assert'
static_assert( false, "test" );
^
./path/to/source.c:57:62: error: enumerator value for '_PDCLIB_assert_571' is not an integer constant
...
It's not pretty, but it's perfectly C89-compliant, tested, and servicable.
Feel free to rename from _PDCLIB_*
to anything you prefer.