Forum: Compiler & IDEs struct-Pointer mit benannten Werten initialisieren


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

ist es möglich, über einen Zeiger auf ein struct benannte Werte zu 
hinterlegen? Sprich: Ich will die GNU-Erweiterung nutzen, in einem 
Struct die Elemente per Namen zuzuweisen (d.h. ein anonymes Struct mit 
nur den benannten Elementen besetzt zu erzeugen und einem anderen Struct 
zuweisen).

Vielleicht läßt es sich mit Quelltext besser erklären:
1
typedef struct
2
{
3
   int a;
4
   int b;
5
} S_t;
6
7
8
void foo()
9
{
10
   S_t a = {.a = 1, .b = 0};
11
   buffer int[2];
12
   S_t *pb = (S_t *) &buffer[0];
13
14
   // Das will nicht:
15
   *(pb) = {.a = 1, .b = 0};
16
17
   // Das ist kein Problem:
18
   *(pb) = a;
19
}

Ja - das ist heftiges type punning, hat aber im Kontext (auf einem 
kleinen µC einen einzelnen Puffer für viele I2C-Daten mit vielen 
Bitfields nutzen) einen Sinn.

Das gleiche Spiel auch bei einem union:
1
void bar()
2
{
3
   union
4
   {
5
      S_t S;
6
   } Buf;
7
8
   // Das will nicht:
9
   Buf.S = {.a = 1, .b = 0};
10
11
   // Jetzt zwinge ich Dich halt:
12
   Buf.S = (S_t) {.a = 1, .b = 0};
13
}

Also die Frage: Was mache ich falsch, wenn ich einem struct über einen 
Zeiger ein anonymes struct zuweisen will?

Viele Grüße
W.T.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Walter T. schrieb:
>    Buf.S = (S_t) {.a = 1, .b = 0};

Geht doch und entspricht der korrekten Syntax. Wo ist dein Problem?

von Walter T. (nicolas)


Lesenswert?

Johann L. schrieb:
> Wo ist dein Problem?

Warum muß ich bei dieser Zuweisung casten:
1
Buf.S = (S_t) {.a = 1, .b = 0};

und bei dieser Zuweisung nicht:
1
S_t a = {.a = 1, .b = 0};

In beiden Fällen weise ich einem struct vom Typ S_t ein anonymes struct 
(nennt man das so?) zu.

von Rolf Magnus (Gast)


Lesenswert?

Walter T. schrieb:
> Johann L. schrieb:
>> Wo ist dein Problem?
>
> Warum muß ich bei dieser Zuweisung casten:
> Buf.S = (S_t) {.a = 1, .b = 0};

Woher soll der Compiler sonst wissen, was er mit {.a = 1, .b = 0} 
anfangen soll? Die linke Seite der Zuweisung hat keinerlei Einfluss auf 
den Typ der rechten Seite.

> und bei dieser Zuweisung nicht:
> S_t a = {.a = 1, .b = 0};

Weil das keine Zuweisung, sondern eine Initialisierung ist.

> In beiden Fällen weise ich einem struct vom Typ S_t ein anonymes struct
> (nennt man das so?) zu.

Nein. Im 1. Fall weist du einer struct ein "compound literal" zu. Dieses 
muss aber einen Typ haben, den du angeben mußt. Im zweiten Fall wird 
einfach eine struct erzeugt und bekommt gleich Initialisierungswerte 
mit.

von Daniel A. (daniel-a)


Lesenswert?

Walter T. schrieb:
> Warum muß ich bei dieser Zuweisung casten:Buf.S = (S_t) {.a = 1, .b =
> 0};

Das ist kein Cast, sondern ein Compound Literal.Du erstellst ein Objekt 
S_t und überschreibst das andere dann damit.

Walter T. schrieb:
> und bei dieser Zuweisung nicht:S_t a = {.a = 1, .b = 0};

Das ist keine Zuweisung, das ist eine Initialisierung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.