Как утверждать, что два типа равны в c?
Используйте _Generic
, чтобы получить вас, по крайней мере, в основном с типами, не являющимися массивами.
#define compare_types(T1, T2) _Generic(( (T1){0} ), \
T2: "Same", \
default: "Different" \
)
#include <stdio.h>
#include <stdint.h>
int main() {
// Same range
printf("%ld %lld\n", LONG_MAX, LLONG_MAX);
// Same size
printf("%zu %zu\n", sizeof (long), sizeof (long long));
// Yet different
printf("%s\n", compare_types(long, long long));
// int64_t is a long on my machine
printf("%s\n", compare_types(long, int64_t));
printf("%s\n", compare_types(long long, int64_t));
}
Вывод
9223372036854775807 9223372036854775807
8 8
Different
Same
Different
Улучшено
Далее, более сильное сравнение использует тесты A vs B
и B vs A
.Эти 2 теста полезны для управляющего выражения: _Generic
преобразует массивы в указатели первого элемента, теряя некоторую информацию о типе.
#define strong_helper(T1, T2) _Generic(( (T1){0} ), \
T2: 1, \
default: 0 \
)
#define compare_types_strong(T1, T2) (strong_helper(T1,T2) && strong_helper(T2,T1))
printf("%d\n", compare_types_strong(long, int64_t));
printf("%d\n", compare_types_strong(int [3], int *));
Выход
1
0
По-прежнему проблематично для массивов и void
compare_types_strong(int [3], int [3])
возвращает 0, когда _Generic
преобразовал управляющее выражение int [3]
в указатель на первый тип элемента (int *
).
@ PSkocik в удаленном комментарии указывает, что этот подход не будет работать для неполного типа объекта void
.