Flexible Array Member
-
Hallo
Ich habe in meinem Code die beiden folgenden Strukturen:
typedef struct IrLMP_Ctl { uint8_t opcode; uint8_t info[]; } IrLMP_Ctl;
typedef struct IrLMP_Frame { IrLMP_Head head; union { IrLMP_Ctl ctl; uint8_t info[]; } u; } IrLMP_Frame;
Flexible-Array-Members sind bestandteil von ANSI C99. Dies habe ich meinem gcc mitgeteilt. Die erste Struktur wird ohne weiteres kompiliert, doch bei der zweiten Struktur kann er die FAM nicht schlucken.
Kann dies in der Art überhaupt funktionieren?
Was passiert wenn ich bei der Instanzierung eines IrLMP_Frame-Objekts ein Array anlegen will das grösser als die IrLMP_Ctl-Struktur ist?Vielen Dank
Ratio
-
Bin zu faul es zu complieren, aber so sollte es funktionieren.
typedef struct IrLMP_Frame { IrLMP_Head head; union { IrLMP_Ctl ctl; uint8_t *info; } u; } IrLMP_Frame;
Wenn Du info intalizierst dann weisst einen Pointer in den Arbeitsspeicher auf info zu, aenderst aber dabei nicht die Groesse des Pointers, so dass den Wert des Pointers (info) ueber ctl abfragen kannst.
-
Danke, das leuchtet mir ein...!
Habe eben noch das ISO-Dokument für C99 durchgestöbert. Die FAM werden als Spezialfälle innerhalb von Structs bezeichnet. Von einer Verwendung innerhalb von Unions ist keine Rede.
Weshalb der Code dann in der Art aufgebaut war ist mir noch etwas unklar!
Grüsse, Ratio
-
"A structure or union shall not contain a member with incomplete or function type [...], except that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union containing, possibly
recursively, a member that is such a structure) shall not be a member of a structure or an
element of an array." (6.7.2.1)Das heißt:
typedef struct IrLMP_Frame { IrLMP_Head head; union { IrLMP_Ctl ctl; /* geht nicht! IrLMP_Ctl enthält ein flexible array member und darf deshalb nicht (auch nicht innerhalb einer union) in der Struktur IrLMP_Frame vorkommen! */ uint8_t info[]; /* geht nicht! in unions gibt es keine flexible array mambers, nur in strukturen! */ } u; } IrLMP_Frame;