Как утверждать, что два типа равны в c? - PullRequest
0 голосов
/ 18 декабря 2018

Как я могу утверждать, что два типа равны в C?В C ++ я бы использовал std :: is_same, но поиск в StackOverflow и в других местах, похоже, дает результаты только для C ++ и C #.Разве нет способа сделать это в C?


Обратите внимание, это не вопрос, имеет ли переменная определенный тип, а скорее, являются ли два типа одинаковыми.

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Как утверждать, что два типа равны в 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.

0 голосов
/ 18 декабря 2018

В gcc вы можете сделать что-то вроде этого:

#define same_type(a, b) \ 
    static_assert(__builtin_types_compatible_p(typeof(a), typeof(b)), "types do not match")

...

int a, b;
float c;
same_type(a,b);
same_type(a,c);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...