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é plusieurs manières avec parent_t
et struct _parent
, mais mon compilateur n'acceptera pas.
Comme une astuce, 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 dummy
?
Bien que définir la taille du tampon avec un #define
soit une façon idiomatique de le faire, une autre solution consisterait à utiliser une macro comme celle-ci:
#define member_size(type, member) sizeof(((type *)0)->member)
et l'utiliser comme ça:
typedef struct
{
float calc;
char text[255];
int used;
} Parent;
typedef struct
{
char flag;
char text[member_size(Parent, text)];
int used;
} Child;
En fait, je suis un peu surpris que sizeof((type *)0)->member)
soit même autorisé comme expression constante. Truc cool.
Je ne suis pas actuellement sur ma machine de développement, mais je pense que vous pouvez effectuer l'une des opérations suivantes:
sizeof(((parent_t *)0)->text)
sizeof(((parent_t){0}).text)
Utilisez une directive de préprocesseur, c'est-à-dire #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 êtes libre d'utiliser FIELD_SIZEOF(t, f)
dans le noyau Linux . Il est simplement défini comme suit:
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
Ce type de macro est mentionné dans d'autres réponses. Mais il est plus portable d’utiliser une macro déjà définie.
Vous pouvez utiliser une directive de préprocesseur pour la taille, comme suit:
#define TEXT_MAX_SIZE 255
et l'utiliser à la fois parent et enfant.
Une autre possibilité serait de définir un type. Le fait que vous souhaitiez garantir la même taille pour les deux champs est un indicateur du fait 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.
sizeof (Type :: membre) semble également fonctionner:
struct Parent
{
float calc;
char text[255];
int used;
};
struct Child
{
char flag;
char text[sizeof(Parent::text)];
int used;
};
struct.h
les a déjà définis,
#define fldsiz(name, field) \
(sizeof(((struct name *)0)->field))
afin que vous puissiez,
#include <stdlib.h> /* EXIT_SUCCESS */
#include <stdio.h> /* printf */
#include <struct.h> /* 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 apparaît qu'il s'agit d'un problème BSD et non de la norme ANSI ou POSIX. Je l'ai essayé sur une machine Linux et cela n'a pas fonctionné; utilité limitée.
@ joey-adams, merci!
#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])