Question C: taille du membre unique struct


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

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

Maintenant, je veux déclarer une structure 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 l'utilisation de dummy?


79
2017-08-24 03:06


origine


Réponses:


Bien que définissant la taille du tampon avec un #define est une façon idiomatique de le faire, une autre serait d'utiliser une macro comme ceci:

#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 en fait un peu surpris que sizeof((type *)0)->member) est même autorisé comme une expression constante. Truc cool.


145
2017-08-24 03:13



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)


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


24
2017-08-24 03:12



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 ;

9
2017-08-24 03:10



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.


4
2017-08-24 03:10



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.


4
2017-08-24 05:47



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 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.


4
2018-06-13 22:25



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;
};

3
2018-02-26 12:47



Vous êtes libre d'utiliser sizeof_field(type, filed) sous Linux. Il 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.


2
2018-03-13 05:27



@ 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])

0
2017-09-30 09:12