2013-02-20 2 views
18

Использование только особенности C89, учитываяПричина в 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; 
+0

Я полагаю, предупреждение компилятора не достаточно хорошо? –

+0

@NikosC. Если скомпилировано с '-Werror', предупреждение станет ошибкой, так что это, вероятно, хорошо. – Kevin

+0

Я бы предпочел жесткую ошибку по эксплуатационным причинам (не имея необходимости гасить с CFLAGS в зонде autoconf), но предупреждение будет сделано. – zwol

ответ

7

Я думаю, вы должны быть в состоянии использовать строгую проверку типов extern объявлений:

typedef int T1; 
typedef char T2; 

extern T1 t1;  
T2 t1; 

выше не будет компилироваться. Изменение T2 на int позволит правильному построению источника.

Это также не компилируется:

typedef int T1; 
typedef unsigned int T2; 

extern T1 t1;  
T2 t1; 

Даже если оба типа int. Я думаю, это то, что вы хотите.

Однако, это не вызовет ошибку:

typedef emum {Foo} T1; 
typedef unsigned T2; 

Так что это не 100% водонепроницаемым. Однако следует иметь в виду, что с enum ничего нельзя сделать, что также невозможно сделать с помощью unsigned. Они имеют одинаковую компоновку и могут использоваться взаимозаменяемо. Фактически, они одного типа.

+0

Ницца! Да, это поведение, которое я хочу. Я собираюсь проверить, что именно стандарт говорит об этой конструкции, прежде чем я приму свой ответ, но я уверен, что вы правы. – zwol

+0

При проверке C99 это не работает, если 'T1' или' T2' или оба являются неполными. Это можно сделать, сделав обе декларации «t1» указателями на «T1» и «T2» соответственно. Кроме того, технически для этого требуется, чтобы T1 и T2 были * совместимыми * типами. Это оказывается намного ближе к «тому же типу», чем я помню, и, вероятно, сделаю для своих целей, но мне все еще любопытно, можно ли обнаружить строгое равенство типов. – zwol

+0

@ Zack Я не уверен, что вы имеете в виду. Если типы не совпадают, я не могу их скомпилировать. Можете ли вы привести пример, где он компилируется, в то время как типы не совпадают? –

2
T1 t1; 
T2 *t2 = &t1; 

Это нарушение ограничения, если T1 и T2 не совпадают.

Или

T1 f(); 
T2 f() {} 
+0

Они также обнаруживают * совместимые типы *, а не * тот же * тип. – zwol

+0

Хм. Разве последние не требуют * одинакового * типа, а не только совместимого? –

+0

Подход типа возвращаемого типа прототипа функции имеет те же результаты, что и ответ «extern», в том числе не перехватывая 'enum' vs' unsigned' как разные. –