rvalue -> lvalue*
-
Nachtrag: Sauberer:
#define MAKE_POINTER(type, value) (&((struct{type x;}){(value)}).x)
-
@camper: Wie meinst du das?
@ würstli: Dein Macro erzeugt den gleichen Fehler
Fehler: Als Operand für unäres »&« wird L-Wert erfordert@ seldon: Das funktioniert, vielen Dank
Was machen denn die {}-Klammern um value bzw. wieso sind die nötig, damit es fehlerfrei kompiliert?
-
Damit wird ein unbennantes, temporäres Objekt einer nicht näher benannten Struktur erzeugt und die Adresse des Members x zurückgeliefiert.
Damit x den Wert value hat, muss die Initialisierungsliste aufgerufen werden.
Voll ausgeschrieben wäre das Konstrukt:struct foo { type x; }; struct foo f{value}; &f.x;
, wenn ich mich nicht irre.
-
Es handelt sich um ein compound literal.
-
Alles klar, danke sehr.
-
Wurstinator schrieb:
@camper: Wie meinst du das?
Das es ein bisschen zu spät war, um vernünftig zu antworten :p
Im Vergleich zu temporären Objekten in C++ leben diese compound literale länger: bis zum Ende des Blocks, als ob sie als lokale Variablen deklariert worden wären.
-
camper schrieb:
C kennt keine temporären Objekte.
Dann lies mal im C11 Standard-Draft nach. Da sind sie nämlich definiert als Objekte mit "temporary lifetime" bei struct/union mit Array-Elementen.
-
Wutz schrieb:
camper schrieb:
C kennt keine temporären Objekte.
Dann lies mal im C11 Standard-Draft nach. Da sind sie nämlich definiert als Objekte mit "temporary lifetime" bei struct/union mit Array-Elementen.
Danke für den Hinweis.
Das bedeutet im Prinzip, dass ein C11-Compiler in bestimmten Fällen kopieren muss, wo das zuvor nicht erforderlich war.
-
Ja, aber nur bei dort titulierten "non-lvalues", also z.B. bei struct als Funktionsrückgabe in der Form:
struct bla { int x[100]; }; struct bla f() {...} und dann int *x = f().x;
-
Wutz schrieb:
Ja, aber nur bei dort titulierten "non-lvalues", also z.B. bei struct als Funktionsrückgabe in der Form:
struct bla { int x[100]; }; struct bla f() {...} und dann int *x = f().x;
Schon klar. Wobei der Zeiger nat. noch im selben Ausdruck konsumiert werden müsste.
Die Tatsache, dass C bei Rückgabe einer Struktur keine Kopie anlegen muss, ist imo eine der wenigen Punkte, in denen C gegenüber C++ einen Vorteil hat.
Von der Entwicklung her sieht es ja so aus:
C89: die Umwandlung in Zeiger ist nur für lvalue-Arrays möglich
C99: Zeigerumwandlung möglich, aber es bleibt unspezifiert, ob das Array eine andere Identität als alle anderen Arrays des Programmes hat.
C11: die Frage wäre geklärt.