webentwicklung-frage-antwort-db.com.de

größe eines einzelnen Strukturmitglieds in C

Ich versuche, eine Struktur zu deklarieren, die von einer anderen Struktur abhängig ist. Ich möchte sizeof verwenden, um sicher/pedantisch zu sein.

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

Jetzt möchte ich eine Struktur child_t deklarieren, die die gleiche Größe wie parent_t.text hat.

Wie kann ich das machen? (Pseudo-Code unten.)

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

Ich habe verschiedene Möglichkeiten mit parent_t und struct _parent ausprobiert, aber mein Compiler akzeptiert dies nicht.

Als Trick scheint das zu funktionieren:

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

Ist es möglich, child_t ohne die Verwendung von dummy zu deklarieren?

88
kevinarpe

Das Definieren der Puffergröße mit einem #define ist zwar eine idiomatische Methode, aber eine andere wäre die Verwendung eines Makros wie folgt:

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

und benutze es so:

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

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

Ich bin eigentlich etwas überrascht, dass sizeof((type *)0)->member) sogar als konstanter Ausdruck erlaubt ist. Cooles Zeug.

158
Joey Adams

Ich bin momentan nicht auf meinem Entwicklungscomputer, aber ich denke, Sie haben folgende Möglichkeiten:

sizeof(((parent_t *)0)->text)

sizeof(((parent_t){0}).text)


Edit : Ich mag das member_size-Makro, das Joey mit dieser Technik vorgeschlagen hat.

25
Brandon Horsley

Verwenden Sie eine Präprozessor-Direktive, z. B. #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
dave mankoff

Sie können FIELD_SIZEOF(t, f) frei im Linux-Kernel verwenden.

#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))

Diese Art von Makro wird in anderen Antworten erwähnt. Es ist jedoch portabler, ein bereits definiertes Makro zu verwenden.

6
Dmitry Gladkov

Sie können eine Präprozessoranweisung für size verwenden als:

#define TEXT_MAX_SIZE 255

und verwenden Sie es bei Eltern und Kind.

4
codaddict

Eine andere Möglichkeit wäre, einen Typ zu definieren. Die Tatsache, dass Sie die gleiche Größe für die beiden Felder sicherstellen möchten, ist ein Indikator dafür, dass Sie dieselbe Semantik haben, denke ich.

typedef char description[255];

und dann ein Feld haben

description text;

in beiden Arten.

4
Jens Gustedt

c ++ - Lösung:

sizeof (Type :: member) scheint ebenfalls zu funktionieren:

struct Parent
{
    float calc;
    char text[255];
    int used;
};

struct Child
{
    char flag;
    char text[sizeof(Parent::text)];
    int used;
};
4
korish

struct.h hat sie bereits definiert,

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

so könntest du,

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

beim Blick in den Header scheint es sich jedoch um eine BSD-Sache und nicht um den ANSI- oder POSIX-Standard zu handeln. Ich habe es auf einem Linux-Rechner ausprobiert und es hat nicht funktioniert; eingeschränkter Nutzen.

4
Neil Edelman

@ joey-adams, danke! Ich suchte dasselbe, aber für ein Array ohne Zeichen und es funktioniert auch so:

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

Es wird wie erwartet 20 zurückgegeben.

@ Brandon-horsley, das funktioniert auch gut:

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