Search code examples
ctypesassert

How to assert two types are equal in c?


How do I assert that two types are equal in C? In C++, I would use std::is_same, but searching StackOverflow and elsewhere seems only to give results for C++ and C#. Is there no way to do this in C?


Note, this is not asking whether a variable has a certain type but rather whether two types are the same.


Solution

  • How to assert two types are equal in c?

    Use _Generic to get you at least mostly there with non-array types.

    #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));
    }
    

    Output

    9223372036854775807 9223372036854775807
    8 8
    Different
    Same
    Different
    

    Improved

    Further, a stronger compare employs a A vs B and B vs A test. The 2 tests are useful for the controlling expression of _Generic converts arrays to pointers of the first element losing some type information.

    #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 *));
    

    Output

    1
    0
    

    Still troublesome for arrays and void

    compare_types_strong(int [3], int [3]) returns 0 as _Generic converted the controlling expression int [3] to a pointer to the first element type (int *).

    @PSkocik, in a deleted comment, points out this approach will not work for the incomplete object type void.