C: Initialisieren eines union

Hallo,

Ich stehe wohl gerade auf dem Schlauch :frowning:
Ausnahmsweise dreht es sich nicht um MSC, sondern um einen Compiler von IAR für eine H8-CPU:

typedef struct
 {
 ........
 } BMAP;

typedef union
 {
 char \*s;
 BMAP \*b;
 } Obj;

BMAP a;

Obj o1 = {"abcdef"};
Obj o2 = {&a}; // das geht nicht
Obj o3 = ((char \*) &a}; // geht, ist halt unschön

So wie es aussieht nimmt der Compiler den Typ, welcher als erster in
typedef union {…} Obj
angegeben wird. Wenn ich die beiden Zeilen im typedef vertausche funktioniert BMAP aber der String muss gecastetd werden.

Ist das normales C-Verhalten oder fehlt mir der richtige Trick ??

MfG peter(TOO)

Hallo Peter,

typedef union
{
char *s;
BMAP *b;
} Obj;

BMAP a;

Obj o1 = {„abcdef“};
Obj o2 = {&a}; // das geht nicht
Obj o3 = ((char *) &a}; // geht, ist halt unschön

So wie es aussieht nimmt der Compiler den Typ, welcher als
erster in typedef union {…} Obj angegeben wird.

Ist das normales C-Verhalten oder fehlt mir der richtige Trick??

Das ist „normales“ C-Verhalten:

Bei einer Union kann eine Initialisierung nur mit der ersten
Alternative erfolgen. So sagt es mein ISO-C-Lehrbuch
ISBN 3519029995 Buch anschauen, S. 241.

Mit ISO-C-99 kannst Du allerdings auch mit Hilfe des Elementbezeichners
ein beliebiges Union-Element für die Initialisierung verwenden, siehe
http://www.oreilly.de/catalog/cinanutger/chapter/ch1…, „Initialisierung von Unions“, also

Obj o3 = { .b = &a };

Zu was brauchst Du denn die Union, ist Dein Speicher zu knapp?

Gruß,
-Andreas.

Hallo Andreas,

Mit ISO-C-99 kannst Du allerdings auch mit Hilfe des
Elementbezeichners
ein beliebiges Union-Element für die Initialisierung
verwenden, siehe
http://www.oreilly.de/catalog/cinanutger/chapter/ch1…,
„Initialisierung von Unions“, also

Obj o3 = { .b = &a };

Der Compiler ist wohl noch nicht ISO-99 ;-((

Zu was brauchst Du denn die Union, ist Dein Speicher zu knapp?

Bei Microcontrollern immer :wink:

Es geht um Ausgabe-Texte eines Gerätes.
Zeiger sind 20-Bit Bit lang, belegen also 4 Byte (alignment).
Definiert sind bis jetzt 12 Sprachen, macht also 48 Byte nur für die Zeiger für jeden Ausgabe-Text.
Die Ausgabe kann nun aber aus ASCII-Zeichen oder einer Pixelgraphik bestehen. Mit ein paar Zeilen Assembler kann ich auf Grund des Segments dann entscheiden ob es ein ASCII-Text oder eine Graphik ist. Zwangsweise liegt sowieso alles im ROM.

MfG Peter(TOO)

Hallo Peter,

Zu was brauchst Du denn die Union, ist Dein Speicher zu knapp?

Bei Microcontrollern immer :wink:

Es geht um Ausgabe-Texte eines Gerätes.
Zeiger sind 20-Bit Bit lang, belegen also 4 Byte (alignment).
Definiert sind bis jetzt 12 Sprachen, macht also 48 Byte nur
für die Zeiger für jeden Ausgabe-Text.
Die Ausgabe kann nun aber aus ASCII-Zeichen oder einer
Pixelgraphik bestehen. Mit ein paar Zeilen Assembler kann ich
auf Grund des Segments dann entscheiden ob es ein ASCII-Text
oder eine Graphik ist. Zwangsweise liegt sowieso alles im ROM.

Aha, klingt interessant. Hatte bisher noch nicht mit hardwarenaher
Programmierung zu tun, reaktiviere aber gerade meine verstaubten
C-Kenntnisse. Deshalb finde ich solche Blicke über den Tellerrand
ziemlich spannend, da es sich nicht auf den ersten Blick erschliesst,
zu was man so eine Union überhaupt sinnvoll einsetzen kann.

Gruß,
-Andreas.

Hallo Andreas,

Aha, klingt interessant. Hatte bisher noch nicht mit
hardwarenaher
Programmierung zu tun, reaktiviere aber gerade meine
verstaubten
C-Kenntnisse. Deshalb finde ich solche Blicke über den
Tellerrand
ziemlich spannend, da es sich nicht auf den ersten Blick
erschliesst,
zu was man so eine Union überhaupt sinnvoll einsetzen kann.

Unions benötige ich sonst noch sehr viel im Zusammenhang mit Meldungen und Übertragungsprotokollen.

Normalerweise hat man dabei einen Header aus welchem sich dann der die restliche Datenstruktur erkennen lässt.
Manche Programmierer definieren den Nutzteil einfach als „char[]“ und zerpflücken das ganze dann im Programm …
Bei mir findest du in der Hauptroutine dann meist ein union mit allen möglichen Strukturen. Die Auswertung wird dann aber schon in unterschiedlichen Funktionen getätigt, welche nur „ihre“ Struktur übergeben bekommen.

MfG Peter(TOO)
Ich habe das Ganze jetzt mit einem
#define BMP (char *)
gelöst. Damit sollte der Source besser lesbar sein.

Mit ISO-C-99 kannst Du allerdings auch mit Hilfe des

[…]

„Initialisierung von Unions“, also

Obj o3 = { .b = &a };

Der Compiler ist wohl noch nicht ISO-99 ;-((

Mir C90 geht es nicht standardkonform: http://www.dclc-faq.de/kap9.htm#9.12

Aber du hast das Problem ja inzwischen gelöst.