Ich versuche, eine Struktur zu deklarieren, die von einer anderen Struktur abhängig ist. Ich möchte benutzen sizeof sicher/pedantisch sein.
typedef struct _parent
{
float calc ;
char text[255] ;
int used ;
} parent_t ;
Jetzt möchte ich eine Struktur deklarieren child_t das hat die gleiche größe wie parent_t.text.
Wie kann ich das machen? (Pseudocode unten.)
typedef struct _child
{
char flag ;
char text[sizeof(parent_t.text)] ;
int used ;
} child_t ;
Ich habe versucht, ein paar verschiedene Möglichkeiten mit parent_t und struct _parentaber mein Compiler akzeptiert nicht.
Als Trick scheint das zu funktionieren:
parent_t* dummy ;
typedef struct _child
{
char flag ;
char text[sizeof(dummy->text)] ;
int used ;
} child_t ;
Kann man deklarieren child_t ohne Verwendung von dummy?
Joey Adams
Obwohl die Puffergröße mit a definiert wird #define ist eine idiomatische Möglichkeit, dies zu tun, eine andere wäre, ein Makro wie dieses zu verwenden:
Das wundert mich tatsächlich etwas sizeof(((type *)0)->member) ist sogar als konstanter Ausdruck erlaubt. Cooles Zeug.
Wow, ich wusste nicht, dass sizeof((type *)0)->member) funktioniert. Bin jetzt nicht auf meinem Entwicklungscomputer, aber funktioniert das für alle Compiler? Danke dafür Joey.
– Gangadhar
24. August 2010 um 5:03 Uhr
@Gangadhar: Ja, das funktioniert für alle Compiler. Der Operand von sizeof wird nicht ausgewertet, daher gibt es kein Problem mit der Dereferenzierung des Nullzeigers (weil er nicht wirklich dereferenziert wird).
@XavierGeoffrey: Hier leitet sizeof den Typ von ((type *)0)->member ab und gibt die Größe dieses Typs zurück. ((type *)0) ist nur ein Nullzeiger vom Typ struct. ptr->member ist (zur Kompilierzeit) ein Ausdruck, dessen Typ der des Members ist. Der Code innerhalb der Größe von wird nie ausgeführt (wenn dies der Fall wäre, würde das Programm einen Segfault ausführen!). Es wird nur der Werttyp innerhalb von sizeof betrachtet.
– Joey Adams
29. September 2014 um 21:13 Uhr
Das Wikipedia-Seite für offset_of bemerkt dies als undefiniertes Verhalten gemäß dem C-Standard, daher würde ich nicht darauf wetten, dass es mit allen Compilern funktioniert.
– Graeme
3. August 2015 um 15:49 Uhr
Ich bin gerade nicht auf meinem Entwicklungscomputer, aber ich denke, Sie können einen der folgenden Schritte ausführen:
Bearbeiten: Ich mag das von Joey vorgeschlagene member_size-Makro mit dieser Technik, ich denke, ich würde das verwenden.
Die zweite Form ist sehr schön (und konzeptionell sauber, da sie keine Nullzeiger enthält), aber Sie sollten erwähnen, dass dies in Compilern vor C99 nicht möglich ist.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
25. August 2010 um 0:09 Uhr
Wenn die Struktur sehr groß ist und der Speicher eine Einschränkung darstellt, sollte zuerst eine bevorzugt werden. korrigiert mich jemand, wenn ich falsch liege.
– PunyCode
3. August 2021 um 5:20 Uhr
@PunyCode – die sizeof Der Operand wird zur Kompilierzeit ausgewertet, also kein Speicherproblem.
– Johann Gerell
22. November 2021 um 14:23 Uhr
Dmitri
Die Nutzung steht Ihnen frei FIELD_SIZEOF(t, f) im Linux-Kernel. Es ist einfach wie folgt definiert:
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
Diese Art von Makro wird in anderen Antworten erwähnt. Aber es ist portabler, ein bereits definiertes Makro zu verwenden.
FIELD_SIZEOF ist das Makro, das in modernen Linux-Kerneln verwendet wird und in linux/kernel.h zu finden ist
– Colin Ian König
18. September 2017 um 9:38 Uhr
@ColinIanKing Das ist also ein idiomatischer Weg in C im Allgemeinen, um die Größe des Strukturmitglieds zu erhalten? Ist ein solches Makro noch nicht in einem Standard in modernem C enthalten?
– St.Antario
19. Dezember 2018 um 5:32 Uhr
Meines Wissens gibt es in Standard-C kein entsprechendes Makro.
@AndriyMakukha Ich bin auch darauf gestoßen … es heißt jetzt sizeof_field (<linux/stddef.h>) ohne Nettoänderung, nur eine Umbenennung.
– mirabilos
13. Juli um 21:23 Uhr
Verwenden Sie eine Präprozessordirektive, dh #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 ;
Sie können eine Präprozessordirektive für die Größe wie folgt verwenden:
#define TEXT_MAX_SIZE 255
und verwenden Sie es sowohl bei Eltern als auch bei Kindern.
ja, aber es ist nicht immer eine Option: Sagen wir unter Linux /usr/include/bits/dirent.h Die grosse von d_name Feld (Struktur direct / dirent) ist nicht definiert als DIRSIZ nicht mehr, aber fest codiert; Also sizeof() scheint die einzig saubere Möglichkeit zu sein, die Abhängigkeit zu halten
– ジョージ
21. Januar 2012 um 17:08 Uhr
Neil
struct.h hat sie bereits definiert,
#define fldsiz(name, field) \
(sizeof(((struct name *)0)->field))
aber beim Blick in die Kopfzeile scheint es, dass dies eine BSD-Sache und kein ANSI- oder POSIX-Standard ist. Ich habe es auf einem Linux-Rechner versucht und es hat nicht funktioniert; begrenzte Nützlichkeit.
ja, aber es ist nicht immer eine Option: Sagen wir unter Linux /usr/include/bits/dirent.h Die grosse von d_name Feld (Struktur direct / dirent) ist nicht definiert als DIRSIZ nicht mehr, aber fest codiert; Also sizeof() scheint die einzig saubere Möglichkeit zu sein, die Abhängigkeit zu halten
– ジョージ
21. Januar 2012 um 17:08 Uhr
Jens Gustedt
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 für sie die gleiche Semantik haben, denke ich.
typedef char description[255];
und dann ein Feld haben
description text;
bei beiden Typen.
14232700cookie-checksizeof einzelnes Strukturmitglied in Cyes