Gültigkeit von Referenzen in C++

Hallo zusammen!

Wir sind gerade am Diskutieren, was die Gültigkeit von Referenzen (also das Konstrukt in C++, das für all jene geschaffen wurde, die Pointer nicht verstanden haben) betrifft.

Was diesen Code hier betrifft ist ja alles klar:

int \*x;
{
 int y = 1;
 x = &y;
}
printf("%d", \*(int\*)x); // DON'T

Wie aber sieht’s damit aus:

int &x;
{
 int y = 1;
 x = y;
}
printf("%d", (int)x); // DO OR DON'T????

Für Eure mit uns geteilte Weisheit dankt,
Martin

Wie aber sieht’s damit aus:
int &x;
{
int y = 1;
x = y;
}
printf("%d", (int)x); // DO OR DON’T???

Ich bin für „do“, solange man hinter x auch den entsprechenden Speicher hängt. Technisch ist eine Referenz ja ein Pointer, der automatisch dereferenziert wird, damit bekommt man als semantisch äquivalente Schreibweise:

int \_x\_store;
int \*x = &\_x\_store;
{
 int y = 1;
 (\*x) = y; // weist \_x\_store den Wert von y zu
}
printf( "%d", \*x );

Anders wäre auch reference passing wie es in C++ gerne gemacht wird garnicht möglich.

Hi,

ich bin für Don’t, da der Compiler meckern wird. Mann kann keine Referenz erzeugen, ohne sie auch zu initialisieren.

grüße

Hallo Michael!

ich bin für Don’t, da der Compiler meckern wird. Mann kann
keine Referenz erzeugen, ohne sie auch zu initialisieren.

Und jetzt:

int a = 5;
int &x = a;
{
 int y = 7;
 x = y;
}
printf("%d", (int)x); // immer noch DON'T???

So frisst’s nämlich auch der Compiler (dass ihr aber auch immer so pingelig sein müsst…).

lg,
Martin

ich bin für Don’t, da der Compiler meckern wird. Mann kann
keine Referenz erzeugen, ohne sie auch zu initialisieren.

Deshalb die Einschränkung, dass man der Referenz auch eine referenzierte Variable zuordnen muss. Die Frage bezieht sich aber so wie ich das lese darauf, ob durch eine derartige Zuweisung an eine Referenz ein „fremder Stack“ referenziert wird, was nicht der Fall ist. Der Wert der inneren Variable wird ja im referenzierten Speicher abgelegt.

Die Zuweisung an die Referenz erzeugt x86-Assemblercode, der z.B. so aussieht:

1: leal -4(%ebp), %eax
2: movl %eax, -8(%ebp)
3: movl $1, -12(%ebp)
4: movl -8(%ebp), %edx
5: movl -12(%ebp), %eax
6: movl %eax, (%edx)

in %eax ist nach dem leal [1] die Adresse des Ziels der Referenz gespeichert, die Referenz liegt in -8(%ebp) [2].

[3] ist die Initialisierung von y.
[4] lädt die Adresse des Ziels der Referenz nach %edx.
[5] lädt den Inhalt von y nach %eax.
[6] schreibt %eax an die Adresse in %edy, also in die referenzierte Variable.

Es wird also nicht die Adresse der kurzlebigen Variable y verwendet, sondern tatsächlich der Wert dieser Variable gespeichert und die Referenz selber nicht verändert. Also: „DO“.

1 Like

Herzlichen Dank und *
Auf die Idee mir den Assembler-Code anzuschauen hätt’ ich eigentlich selbst kommen können…

Danke nochmal und schönes Wochenende,
Martin