То, что лучший способ состоит в том, чтобы достигнуть статичного времени компиляции, утверждает в C (не C++) с особым акцентом на GCC?
Из Википедии :
#define COMPILE_TIME_ASSERT(pred) switch(0){case 0:case pred:;}
COMPILE_TIME_ASSERT( BOOLEAN CONDITION );
Это работает в функциональной и нефункциональной области видимости (но не внутри структур, объединений).
#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(COND)?1:-1]
STATIC_ASSERT(1,this_should_be_true);
int main()
{
STATIC_ASSERT(1,this_should_be_true);
}
Если утверждение времени компиляции не может быть сопоставлено, то GCC sas.c: 4: error: размер массива static_assertion_this_should_be_true создает почти понятное сообщение.
Макрос может или должен быть изменено, чтобы сгенерировать уникальное имя для typedef (например, объединить __ LINE __
в конце static_assert _...
name)
Вместо тернарного можно также использовать #define STATIC_ASSERT (COND, MSG) typedef char static_assertion _ ## MSG [2 * (!! (COND)) - 1]
, который работает даже на устаревшем компиляторе olde cc65 (для 6502 cpu) .
ОБНОВЛЕНИЕ:
Для полноты картины, вот версия с __ LINE __
#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1]
// token pasting madness:
#define COMPILE_TIME_ASSERT3(X,L) STATIC_ASSERT(X,static_assertion_at_line_##L)
#define COMPILE_TIME_ASSERT2(X,L) COMPILE_TIME_ASSERT3(X,L)
#define COMPILE_TIME_ASSERT(X) COMPILE_TIME_ASSERT2(X,__LINE__)
COMPILE_TIME_ASSERT(sizeof(long)==8);
int main()
{
COMPILE_TIME_ASSERT(sizeof(int)==4);
}
UPDATE2: специальный код GCC
GCC 4.3 (я полагаю) представил атрибуты функций «error» и «warning». Если вызов функции с этим атрибутом не может быть устранен с помощью удаления мертвого кода (или других мер), генерируется ошибка или предупреждение. Это можно использовать для создания утверждений времени компиляции с пользовательскими описаниями ошибок. Осталось определить, как их можно использовать в области пространства имен, не прибегая к фиктивной функции:
#define CTC(X) ({ extern int __attribute__((error("assertion failure: '" #X "' not true"))) compile_time_check(); ((X)?0:compile_time_check()),0; })
// never to be called.
static void my_constraints()
{
CTC(sizeof(long)==8);
CTC(sizeof(int)==4);
}
int main()
{
}
И вот как это выглядит:
$ gcc-mp-4.5 -m32 sas.c
sas.c: In function 'myc':
sas.c:7:1: error: call to 'compile_time_check' declared with attribute error: assertion failure: `sizeof(int)==4` not true