Puis-je ‘étendre’ une structure en C?

typedef struct foo_s { int a; } foo; typedef struct bar_s { foo; int b; } bar; 

Essentiellement je veux faire:

 bar b; ba; 

Je sais que je pourrais faire b.foo_name.a si j’avais nommé le foo struct in bar, mais je préfère ne pas le faire.

Un moyen de faire ça?

Cette question a obtenu une variété de réponses différentes, alors laissez-moi expliquer le besoin. La raison pour laquelle je veux faire cela est parce que j’ai une bibliothèque que je dois m’adapter à ma situation, ce qui signifie que je ne peux pas modifier la struct decleration originale. De plus, tout ce que j’ai à faire est d’append 1 élément au début de la structure (pourquoi le début? Parce que j’ai une structure ‘object’ qui dirige toutes les structures du projet). Je pourrais simplement intégrer la structure comme vous l’avez mentionné, mais c’est VRAIMENT agaçant, car toutes les références devront être saisies ‘variable-> image.location’, cette ‘image’. taper un milliard de types est vraiment ennuyeux.

Il est évident que cette fonctionnalité a été ajoutée à C11 , mais hélas je n’ai pas access à un compilateur C de millésimes récents (> = GCC 4.6.2).

 typedef struct foo { int a; } foo; typedef struct bar { struct foo; int b; } bar; int main() { bar b; ba = 42; bb = 99; return 0; } 

Vous pouvez utiliser des pointeurs, car un pointeur sur un object de structure est garanti pour pointer son premier membre. Voir par exemple cet article .

 #include  #include  typedef struct foo_s { int a; } foo; typedef struct bar_s { foo super; int b; } bar; int fooGetA(foo *x) { return x->a; } void fooSetA(foo *x, int a) { x->a = a; } int main() { bar* derived = (bar*) calloc(1, sizeof(bar)); fooSetA((foo*) derived, 5); derived->b = 3; printf("result: %d\n", fooGetA((foo*) derived)); return 0; } 

Pas possible en C comme tu l’as fait. Mais vous pouvez imiter l’inheritance avec une variable membre foo dans bar .

 typedef struct bar_s { foo obj; int b; } bar; bar b; b.obj.a = 10; 

Si vous mentez

 typedef struct foo_s { int a; } foo; typedef struct bar_s { foo my_foo; int b; } bar; 

alors tu peux faire:

 bar b; b.my_foo.a = 3; 

Sinon, il n’y a aucun moyen de le faire en C puisque la sizeof(bar_s) nuit à la compilation. Ce n’est pas une bonne pratique, mais vous pouvez enregistrer un void * ptr; pointeur dans bar_s, et une autre énumération qui décrit le type ptr et convertie par le type.

c’est à dire:

 typedef enum internalType{ INTERNAL_TYPE_FOO = 0, }internalType_t; typedef struct bar_s { internalType_t ptrType; void* ptr; int b; } bar; 

et alors:

 bar b; foo f; b.ptrType = INTERNAL_TYPE_FOO; b.ptr = &f; 

et d’autres ailleurs dans le code:

  if (b.ptrType == INTERNAL_TYPE_FOO) { foo* myFooPtr = (foo *)b.ptr; } 

Vous pouvez essayer d’utiliser l’inheritance:

 struct foo_s { int a; }; struct bar_s: foo_a { int b; }; 

Fonctionne en C ++, ne sais pas si cela fonctionne en C.

Cela peut se faire facilement via le préprocesseur:

Créez un fichier nommé base_foo.h :

 int foo; 

Puis simplement l’inclure:

 typedef struct foo_s { #include "base_foo.h" } foo; typedef struct bar_s { #include "base_foo.h" int b; } bar;