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