Это работает в функциональной и нефункционной области (но не внутри структур, союзов).
#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);
}
sas.c:4: error: size of array ‘static_assertion_this_should_be_true’ is negative
__LINE__
в конце имени static_assert_...
) #define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[2*(!!(COND))-1]
, который, по-видимому, работает даже на Rusty oldc cc65 (для 6502 процессора). ОБНОВЛЕНИЕ: Для полноты, вот версия с __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 (я думаю) представил атрибуты функции «ошибка» и «предупреждение». Если вызов функции с этим атрибутом не может быть устранен посредством устранения мертвого кода (или других мер), то генерируется ошибка или предупреждение. Это можно использовать для утверждения времени компиляции с описаниями ошибок, определенных пользователем. Остается определить, как они могут использоваться в области пространства имен, не прибегая к фиктивной функции:
#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