C: taille du membre unique struct

J’essaie de déclarer une structure qui dépend d’une autre structure. Je veux utiliser sizeof pour être sûr / pédant.

 typedef struct _parent { float calc ; char text[255] ; int used ; } parent_t ; 

Maintenant, je veux déclarer un struct child_t qui a la même taille que parent_t.text .

Comment puis-je faire ceci? (Pseudo-code ci-dessous.)

 typedef struct _child { char flag ; char text[sizeof(parent_t.text)] ; int used ; } child_t ; 

J’ai essayé de différentes manières avec parent_t et struct _parent , mais mon compilateur n’acceptera pas.

Comme un truc, cela semble fonctionner:

 parent_t* dummy ; typedef struct _child { char flag ; char text[sizeof(dummy->text)] ; int used ; } child_t ; 

Est-il possible de déclarer child_t sans utiliser de dummy ?

Bien que la définition de la taille du tampon avec un #define soit un moyen idiomatique de le faire, une autre consiste à utiliser une macro comme celle-ci:

 #define member_size(type, member) sizeof(((type *)0)->member) 

et l’utiliser comme ceci:

 typedef struct { float calc; char text[255]; int used; } Parent; typedef struct { char flag; char text[member_size(Parent, text)]; int used; } Child; 

Je suis un peu surpris que sizeof((type *)0)->member) soit même autorisé comme expression constante. Truc cool.

Je ne suis pas sur ma machine de développement pour le moment, mais je pense que vous pouvez faire l’une des choses suivantes:

 sizeof(((parent_t *)0)->text) sizeof(((parent_t){0}).text) 

Edit : J’aime la macro member_size que Joey a suggéré d’utiliser cette technique, je pense que je l’utiliserais.

Utilisez une directive de préprocesseur, à savoir #define:

 #define TEXT_LEN 255 typedef struct _parent { float calc ; char text[TEXT_LEN] ; int used ; } parent_t ; typedef struct _child { char flag ; char text[TEXT_LEN] ; int used ; } child_t ; 

Vous pouvez utiliser une directive de préprocesseur pour la taille en tant que:

 #define TEXT_MAX_SIZE 255 

et l’utiliser chez les parents et les enfants.

Une autre possibilité serait de définir un type. Le fait que vous vouliez vous assurer que la même taille pour les deux champs est une indication que vous avez la même sémantique pour eux, je pense.

 typedef char description[255]; 

et ensuite avoir un champ

 description text; 

dans vos deux types.

struct.h a déjà définis,

 #define fldsiz(name, field) \ (sizeof(((struct name *)0)->field)) 

afin que vous puissiez,

 #include  /* EXIT_SUCCESS */ #include  /* printf */ #include  /* fldsiz */ struct Penguin { char name[128]; struct Penguin *child[16]; }; static const int name_size = fldsiz(Penguin, name) / sizeof(char); static const int child_size = fldsiz(Penguin, child) / sizeof(struct Penguin *); int main(void) { printf("Penguin.name is %d chars and Penguin.child is %d Penguin *.\n", name_size, child_size); return EXIT_SUCCESS; } 

mais, en regardant dans l’en-tête, il semble que ce soit une chose BSD et non la norme ANSI ou POSIX. Je l’ai essayé sur une machine Linux et cela n’a pas fonctionné. utilité limitée.

solution c ++:

sizeof (Type :: member) semble également fonctionner:

 struct Parent { float calc; char text[255]; int used; }; struct Child { char flag; char text[sizeof(Parent::text)]; int used; }; 

Vous êtes libre d’utiliser sizeof_field(type, filed) sous Linux. C’est juste défini comme suit:

 #define sizeof_field(type,field) (sizeof(((type *)0)->field)) 

c’est mentionné ci-dessus. Mais il est plus portable d’utiliser une macro déjà définie.

@ joey-adams, merci! Je cherchais la même chose, mais pour les tableaux sans char et cela fonctionne parfaitement, même de cette façon:

 #define member_dim(type, member) sizeof(((type*)0)->member) / \ sizeof(((type*)0)->member[0]) struct parent { int array[20]; }; struct child { int array[member_dim(struct parent, array)]; }; int main ( void ) { return member_dim(struct child, array); } 

Il retourne 20 comme prévu.

Et @ brandon-horsley, cela fonctionne bien aussi:

 #define member_dim(type, member) sizeof(((type){0}).member) / \ sizeof(((type){0}).member[0])