Types et structures compatibles en C

J’ai le code suivant:

int main(void) { struct { int x; } a, b; struct { int x; } c; struct { int x; } *p; b = a; /* OK */ c = a; /* Doesn't work */ p = &a; /* Doesn't work */ return 0; } 

qui ne comstack pas sous GCC (3.4.6), avec l’erreur suivante:

 test.c:8: error: incompatible types in assignment test.c:9: warning: assignment from incompatible pointer type 

D’après ce que je comprends (d’après la norme C99), a et c devraient être des types compatibles, car ils répondent à tous les critères de la section 6.2.7, paragraphe 1. J’ai essayé de comstackr avec std=c99 pour: en vain.

Vraisemblablement, mon interprétation de la norme est fausse?

Addenda

Incidemment, cette question se pose parce que je voulais déclarer des macros similaires à des modèles pour envelopper différents types de données sans la surcharge de devoir déclarer des types / typedefs nommés partout, par exemple un exemple sortingvial:

 #define LINKED_LIST(T) \ struct { \ T *pHead; \ T *pTail; \ } ... LINKED_LIST(foo) list1; LINKED_LIST(foo) list2; ... LINKED_LIST(foo) *pList = &list1; /* Doesn't work */ 

En examinant le projet de spécification, je suppose que vous vous appuyez sur les conditions qui suivent la déclaration:

De plus, deux types de structure, d’union ou énumérés déclarés dans des unités de traduction distinctes sont compatibles si leurs balises et leurs membres répondent aux exigences suivantes …

Je pense que le fait qu’ils soient tous décédés dans le même fichier C signifie qu’ils sont dans une seule unité de traduction.

Il semble donc que cela garantisse que lorsque deux fichiers C incluent un en-tête déclarant un type, les instances de ce type seront compatibles.

struct { int x; } struct { int x; } est une balise de structure anonyme, deux structures anonymes ne peuvent pas avoir “le même nom”, condition nécessaire à la compatibilité de types. Vous pouvez déclarer des types compatibles avec une structure non anonyme à l’aide de typedef .

 struct tmp { int x; }; // declare structure tag typedef struct tmp type1; typedef struct tmp type2; // declare 3 types compatible with struct tmp typedef struct tmp type3; // and with each other type1 a, b; type2 c; type3 *p; b = a; c = a; p = &a; 

Compatibilité des structures, des unions et des énumérations

Dans un même fichier source, chaque définition de structure ou d’union crée un nouveau type qui n’est ni identique ni compatible avec un autre type de structure ou d’union. Cependant, un spécificateur de type qui fait référence à une structure ou à un type d’union précédemment définie est du même type. La balise associe la référence à la définition et agit effectivement comme nom de type. Pour illustrer cela, seuls les types de structures j et k sont compatibles dans cet exemple:

 struct { int a; int b; } h; struct { int a; int b; } i; struct S { int a; int b; } j; struct S k; 

Des structures compatibles peuvent être affectées les unes aux autres.

Fait intéressant, Clang donne ce qui suit:

 error: incompatible type assigning 'struct ', expected 'struct ' warning: incompatible pointer types assigning 'struct  *', expected 'struct  *' 

Il semble que si deux (ou plus) structures anonymes sont déclarées, le compilateur effectue une magie interne qui spécifie également la structure anonyme qui est référée.

Compte tenu des paragraphes 6.2.7 (types compatibles) et 6.5.16.1 (règles d’atsortingbution), je comprends tout à fait comme vous.

Il semble qu’avec votre code, GCC se comporte comme si vos définitions de structure étaient étiquetées avec des balises différentes (ce qui n’est pas le cas). Dans quels cas les types ne seraient pas compatibles. Cependant, cela ressemble toujours à un bug de gcc.

Des commentaires d’autres compilateurs qui implémentent la norme C99?