Используя только функции C89, данные
typedef [unspecified token sequence] T1;
typedef [another unspecified token sequence] T2;
демонстрирует конструкцию языка, которая будет компилироваться без ошибок тогда и только тогда, когда T1 и T2 будут одного типа (а не только совместимы). Ограничение на C89 связано с тем, что оно входит в зонд autoconf.
EDIT: Мне нужно решение, которое работает, даже если T1 или T2 или оба являются неполными. Извините, что не упоминал об этом раньше.
SON OF EDIT: Все три текущих ответа обнаруживают только совместимые типы. Это оказывается намного ближе к "тому же типу", чем я помнил, достаточно близко для моих текущих целей, но из любопытства я все еще ищу ответ, который определяет тот же тип. Вот несколько типов совместимых типов, но не одинаковые:
typedef void (*T1)(void);
typedef void (*T2)();
typedef float T1[];
typedef float T2[12];
typedef enum { ONE, TWO, THREE } T1;
typedef /* implementation-defined integer type */ T2;