С C99 и составными литералами вы можете сделать что-то вроде
#define ASSERT_TYPE(TYPE, VALUE) ((TYPE){ 0 } = (VALUE))
Это гарантирует, что VALUE
совместимо с присвоением TYPE
.Выражение возвращает значение r из-за присваивания.
Составные литералы работают как в области действия функции, так и в области видимости файла, и любой достойный компилятор должен оптимизировать дополнительный объект, который создается путем.* Добавление : TYPE
в этом макросе может быть любым допустимым именем типа, например указатель double*
, структура или объединение struct toto
, кроме массивов.Тип массива, такой как double[4]
, не будет работать из-за назначения.Вместо этого используйте указатель на массив double(*)[4]
, например, как в
double A[4];
(*ASSERT_TYPE(double(*)[4], &A))
, где вторая строка снова является lvalue типа double[4]
, который проверяется на время компиляции для этого свойства.