НОВЫЙ ОТВЕТ :
В моем исходном ответе (ниже) мне нужно было иметь два разных макроса для поддержки утверждений в области функций и в глобальной области. Я задавался вопросом, возможно ли придумать единственное решение, которое будет работать в обеих областях.
Мне удалось найти решение, которое работало бы для компиляторов Visual Studio и Comeau с использованием внешних символьных массивов. Но мне удалось найти более сложное решение, которое работает для GCC. Но решение GCC не работает для Visual Studio. :( Но, добавив '#ifdef __ GNUC __', легко выбрать правильный набор макросов для данного компилятора.
Решение:
#ifdef __GNUC__
#define STATIC_ASSERT_HELPER(expr, msg) \
(!!sizeof \ (struct { unsigned int STATIC_ASSERTION__##msg: (expr) ? 1 : -1; }))
#define STATIC_ASSERT(expr, msg) \
extern int (*assert_function__(void)) [STATIC_ASSERT_HELPER(expr, msg)]
#else
#define STATIC_ASSERT(expr, msg) \
extern char STATIC_ASSERTION__##msg[1]; \
extern char STATIC_ASSERTION__##msg[(expr)?1:2]
#endif /* #ifdef __GNUC__ */
Вот сообщения об ошибках, сообщенные для STATIC_ASSERT(1==1, test_message);
в строке 22 test.c:
GCC:
line 22: error: negative width in bit-field `STATIC_ASSERTION__test_message'
Visual Studio:
test.c(22) : error C2369: 'STATIC_ASSERTION__test_message' : redefinition; different subscripts
test.c(22) : see declaration of 'STATIC_ASSERTION__test_message'
Комео:
line 22: error: declaration is incompatible with
"char STATIC_ASSERTION__test_message[1]" (declared at line 22)
ОРИГИНАЛЬНЫЙ ОТВЕТ :
Я делаю что-то очень похожее на то, что делает Шашки. Но я включаю сообщение, которое будет отображаться во многих компиляторах:
#define STATIC_ASSERT(expr, msg) \
{ \
char STATIC_ASSERTION__##msg[(expr)?1:-1]; \
(void)STATIC_ASSERTION__##msg[0]; \
}
И для выполнения чего-либо в глобальной области видимости (вне функции) используйте это:
#define GLOBAL_STATIC_ASSERT(expr, msg) \
extern char STATIC_ASSERTION__##msg[1]; \
extern char STATIC_ASSERTION__##msg[(expr)?1:2]