Я хочу скомпилировать на компиляторе, в котором не реализован static_assert. Поэтому я хочу, чтобы эти строки стали неактивными.
Почему бы не объединить ответ Лундина (проверяя, имеет ли текущий компилятор реализованный или нет) с реализацией из static_assert
(что не сложно сделать)?
Копирование реализации из PDCLib (что лицензировано CC0 ):
/* 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
Для данного выражения e
и сообщения m это объявляет анонимное перечисление с одним членом, имя которого _PDCLIB_assert_
объединяется с текущей строкой исходного файла (__LINE__
) (так что вы можете иметь несколько static_assert()
за исходный файл). Этот элемент имеет значение 1
, деленное на 1
, если выражение e
является истинным, или делится на 0
, если выражение ложное, что приводит к выводу, подобному этому, для ошибочного утверждения:
./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
...
Это не красиво, но совершенно C89-совместимо, протестировано и обслуживаемо.
Не стесняйтесь переименовывать из _PDCLIB_*
во все, что вы предпочитаете.