packed struct/union in C und C++

Gast #2901863
Lesenswert?

Guten Abend zusammen

Ich habe einen Source Code, der in C wunderbar funktionierte und nun 
auch mit einem C++ Compiler funktionieren soll. So weit so gut... nun 
hab ich das Problem, dass bei folgender Zusweisung

curr_frame->locals[i] = vm_args[i];

im Memory fälschlicherweise jeweils 1 Byte des vorherigen class_ptr mit 
1 Byte Wert von vm_args überschrieben wird. vm_args ist natürlich 
ebenfalls vom Typ value_t. Woran könnte dies liegen?


typedef PACKED struct frame_T      frame_t;
typedef PACKED union value_T       value_t;

struct frame_T
{
    class_t     *class_ptr;
    value_t      locals[1];
};

union value_T
{
    int32   i;
    float32 f;
    uint32  val;
};

Die Struktur sowie die Union wurde mit #pragma pack(2) versehen, da 
diese typen mit dem alignment in einem file übereinstimmen müssen (und 
dies soweit auch tun). Ich benutze IAR als Compiler, die CPU ist ein 
LPC23xx von NXP.

Ich hoffe, die Angaben reichen soweit mal... Danke für eure Hilfe.

Gruss
Fabian
Moderator #2901948
Lesenswert?

Karl Heinz Buchegger schrieb:
> ein Array der Länge 1?

Möglicherweise soll das ein "flexible array member" sein, wobei man
diese seit C99 ohne Größenangabe schreibt, also
1
struct frame_T
2
{
3
    class_t     *class_ptr;
4
    value_t      locals[];
5
};

Egal ob mit oder ohne Größenangabe, in C++ sind solche Dinge m.W.
offiziell nicht vorgesehen (höchstens vielleicht in C++11), könnten aber
trotzdem funktionieren. Ganz sicher kann man aber solche Strukturen
nicht mit new anlegen, da man dort im Gegensatz zu malloc keine
Größe übergibt, die ja in diesem Fall variabel ist.

Vielleicht liegt also der Fehler darin, dass für die Strukturen zu wenig
Speicher reserviert wird.

Welche Absicht aber tatsächlich hinter der [1] steckt, das kann uns nur
Fabian sagen.
Gast #2902379
Lesenswert?

Danke für eure Antworten.

Warum die ganze packerei? Dies hat schon seinen Grund, denn der struct 
ist eigentlich deutlich grösser (dies ist nur das Ende davon...) und 
wird einerseits über bestehende Daten im Flash "gestülpt" und 
andererseits dient es zur Speicherung im RAM. Genau dort liegt das 
Problem.

Genau so ist es, wir reden hier von einem "flexible Array Member". Aber 
warum wird dieses Array nicht richtig addressiert, auch wenn ich im 
Moment nur das Element 0 benutze? Muss zwingend malloc verwendet werden? 
Wurde im C Code übrigens auch nicht...
#2902391
Lesenswert?

Fabian schrieb:
> Die Struktur sowie die Union wurde mit #pragma pack(2) versehen, da
> diese typen mit dem alignment in einem file übereinstimmen müssen

Was soll das, mach ordentliche read und write Funktionen, dann muss gar 
nichts übereinstimmen und es ist portabel.

Fabian schrieb:
> und wird einerseits über bestehende Daten im Flash "gestülpt"

Dasselbe wie oben, das ist Trickprogrammierung. Kann man machen wenn das 
genau für eine Anwendung und einen Prozessor gemacht wird, aber beim 
Portieren immer eine Lotterie.
Wenn man hier nicht unbedingt das letzte halbe Prozent an Performance 
braucht, macht man sowas mit sauberen Konvertierfunktionen.

Meine Meinung!
Gast #2902419
Lesenswert?

Naja, dann poste ich das nächste mal den ganzen Source Code...
Gewisse Leute in diesem Forum werden, sofern sie nicht gerade eine 
Lösung bereit haben, seeehr schnell persönlich. Muss ich nicht haben!

Auch meine Meinung!
#2902436
Lesenswert?

Fabian schrieb:
> Naja, dann poste ich das nächste mal den ganzen Source Code...

Die ganze Struktur wär schon mal ein Ansatz. Denn in der gezeigten 
Struktur ist kein Anlass für einen einzelnen Bytezugriff zu sehen. Aber 
generell gilt es, bei Suche nach hartnäckigen Fehlern das Programm auf 
das Minimum abzuspecken, in dem das Problem immer noch auftritt. Das 
hilft nicht nur beim Posten vom Code, sondern auch dir.

Ausserdem solltest du deinen Code mal auf Stellen untersuchen, in denen 
die Adresse eines misaligned members verwendet wird, statt direkt darauf 
zuzugreifen. Ich weiss nicht wie IAR sich in diesem Fall verhält, aber 
bei GCC kann das grandios und ohne Warnung in die Hose gehen.

> seeehr schnell persönlich

Persönlich geht anders. Allerdings nervt es auf Dauer, wenn immer wieder 
Leute zielsicher genau jene Teile posten, die ziemlich wahrscheinlich 
nicht die Ursache des Problem sind (noch nerviger ist allerdings 
abgetippter Code der Marke "so ähnlich, nur ohne die ganzen Tipp- und 
Syntaxfehler").

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren