void reference?
-
groovemaster2002 schrieb:
template <class T> T& invalid_ref(T* x) { T* tmp = NULL; return *tmp; // hier wird nicht NULL dereferenziert, sondern tmp // und tmp ist eine gültige Variable mit gültigem Speicher // dass tmp ein Zeiger ist, der auf NULL zeigt -> geschenkt // letztendlich wird zwar ein NULL Objekt zurückgegeben, // interessiert hier aber nicht, da ich weder lesend noch // schreibend zugreife } int main() { int a = 1; int& b = invalid_ref(&a); b = 2; // erst hier machts oops, weil ich jetzt auf ein NULL-Objekt // schreibend zugreife }vielleicht solltest du nicht den debugger bemühen, sondern ein gutes Buch?
Der Grund warum er dort oben nicht abschmiert ist wahrscheinlich der, dass Referenzen intern als Zeiger gehandhabt werden und keine Dereferenzierung stattfindet.
Das ist aber Implementierungsabhängig...
-
per definitionem erzeugt das dereferenzieren eines zeigers, der auf NULL zeigt, undefiniertes verhalten - so der standard.
und undefiniertes verhalten heißt, wie der name schon sagt, es kann geschehen, was geschehen will.
-
Der Compiler könnte die Dereferenzierung allerdings wegoptimieren, wenn er sieht, dass der Zeiger dereferenziert und dann direkt an die Referenz übergeben wird, das könnte ich mir auch vorstellen.
-
Der Standard erwähnt sogar ausdrücklich, dass in einem legalen Programm Referenzen auf Null nicht vorkommen können - weil man sie eben nur erzeugen kann, wenn man einen Nullzeiger dereferenziert (8.3.2)
Egal ob der Compiler etwas wegoptimieren kann oder nicht - Wenn es so im Code steht, dann ist es einfach undefiniert, was herauskommt.
-
Ich habe beim MSVC sogar schon ne Referenz angelegt, die ich nicht
initialisiert habe und erst spaeter auf eine Variable habe referenzieren
lassen
Sollte er das eigentlich nicht _nicht_ schlucken?

Soviel zum manchmal komischen Verhalten vom MSVC

mfg
v R
-
Da würde mich ja interessieren, wie du das gemacht hast.
-
Bashar schrieb:
Da würde mich ja interessieren, wie du das gemacht hast.
Na das weisst du doch, war doch damals mit dir im chat und hatte den Code auch
irgendwo auf rafb gepostet gehabt...mal sehn ob ich den wiederfinde. Weiss noch,
dass der Borland-Compiler und der gcc den Code nicht geschluckt hat.War glaub ich sowas in der Art:
int &i; int j; i = j;Ich schau nochmal nach, ansonsten kann ich ja nochmal MSVC installieren und
das ganze nochmal machen.Wenn jemand das Visual Studio.net 2002 hat, sollte er das Ganze nachvollziehen
koennen.mfg
v R
-
davie schrieb:
Der Standard erwähnt sogar ausdrücklich, dass in einem legalen Programm Referenzen auf Null nicht vorkommen können - weil man sie eben nur erzeugen kann, wenn man einen Nullzeiger dereferenziert (8.3.2)
Der Standard spricht nicht von legalen, sondern von "well-defined
program". Und genau mit dieser Aussage bestätigst du, dass sich der Code so verhält, wie ers tut.T* tmp = NULL; return *tmp;Hier passiert nix undefiniertes. Es wird laut Standard eine null reference "erzeugt". Was damit passiert ist undefiniert (geb ja zu, dass dies nicht immer zu einem Absturz führen muss - auch wenn das auf x86 Plattformen die Regel sein wird). Mich störte nur, dass Shade schrieb:
b = 2; // oops :-o //nein, hier kein oopsWenn das Programm nicht irgendwo nach dem return sich undefiniert verhält, hier tut es das auf jeden Fall. Mir geht es aber nicht darum zu streiten, wo's oopst, sondern dass man die "sicheren" Referenzen auch missbrauchen kann.
-
groovemaster2002 schrieb:
Hier passiert nix undefiniertes.
Soll ich dir den Standard vorlesen?
hier mal ganz langsam zum mitschreiben:
in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the "object" obtained by dereferencing a null pointer, which causes undefined behavior.
Was ist daran unverständlich?
Wenn dir "well-defined" nicht gefällt, siehe 1.3.* - dort gibts n paar Erklärungen die du dir mal reinziehen solltest.
-
Sicherlich kann man den Satz unterschiedlich interpretieren, ich lese da 2 Fakten raus:
1. das Dereferenzieren eines Null-Zeigers ergibt immer eine Null-Referenz - da is nix undefiniert dran
2. die Auswirkungen durch die Benutzung einer Null-Referenz sind dagegen undefined, weshalb man sie in einem "well-defined" Programm nicht benutzen soll.
-
du interpretierst ihn aber falsch.
-
mit der zeile
return *tmp;dereferenzierst du einen nullzeiger, zumindest darüber sind wir uns einig?
-
A macht was kaputt, so daß B nicht mehr funktioniert. Wo gehört jetzt das Oops hin? Da wo A was kaputt macht (meine Meinung) oder da wo jemand ahnungsloses versucht B trotzdem zu benutzen?
-
oline schrieb:
du interpretierst ihn aber falsch.
Wieso tust du mir nicht den Gefallen und begründest deinen Standpunkt.
davie schrieb:
dereferenzierst du einen nullzeiger, zumindest darüber sind wir uns einig?
Absolut. Null-Zeiger und nicht NULL, wie einige schrieben.
Und was entsteht laut Standard, wenn man dies tut? Darüber sind wir uns doch auch einig?
-
genau, undefiniertes verhalten.
damit ist alles, was später passiert egal.
-
groovemaster2002 schrieb:
1. das Dereferenzieren eines Null-Zeigers ergibt immer eine Null-Referenz - da is nix undefiniert dran
Dann lies mal
"a null reference cannot exist in a well-defined program"Was kann man daran falsch verstehen?
Weiters siehe 1.9p4
Certain operations are described in this International Standard as undefined (for example dereferencing the null pointer)
Das sind Sachen die man einfach nicht anders interpretieren kann.
btw: well-defined heisst: Programm mit definiertem verhalten - dies bedeutet, not well-defined ist ein "kaputtes" Programm
-
@Jester
Das oops gehört für mich dorthin, wo undefiniertes Verhalten in Erscheinung tritt (ich weiss, dass diese Antwort dich nicht glücklich machen wird
).davie schrieb:
genau, undefiniertes verhalten.
Nein, eben nicht. Es entsteht eine Null-Referenz. Punkt. Bis dorthin gibt es noch kein undefiniertes Verhalten. Alles was danach kommt bzw. mit dieser Null-Referenz angestellt wird, ist undefiniert.
@Shade
Ich würde ja gern was antworten. Nur kann ich deine Argumente nicht mehr ganz nachvollziehen. Nicht dass sie falsch wären, nur von meinem Standpunkt aus habe ich auch nichts anderes behauptet.
-
groovemaster2002 schrieb:
davie schrieb:
genau, undefiniertes verhalten.
Nein, eben nicht. Es entsteht eine Null-Referenz. Punkt. Bis dorthin gibt es noch kein undefiniertes Verhalten. Alles was danach kommt bzw. mit dieser Null-Referenz angestellt wird, ist undefiniert.
Erklaer mir bitte, wie du
"a null reference cannot exist in a well-defined program"
interpretierst.Ich verstehe dies so:
Eine "NULL Reference" kann es nicht geben - somit bedeutet jedes auftreten einer "NULL Reference" undefiniertes Verhalten. Denn der Standard legt fest, dass es eine "NULL Reference" nicht gibt, deshalb kann er nicht definieren was beim auftreten einer "NULL Reference" passiert, ergo ist es nicht definiert (undefiniert)Weiters interpretiere ich
"Certain operations are described in this International Standard as undefined (for example dereferencing the null pointer)"
folgendermassen:Einige Operationen sind undefiniert, darunter faellt auch das dereferenzieren eines NULL Zeigers.
char* tmp=NULL;
dies ist ein NULL Zeiger.*tmp;
dies ist eine Dereferenzierung.Da tmp ein NULL Zeiger ist, wird hier also ein NULL Zeiger derefrenziert, was mit undefiniertem Verhalten bestraft wird.
@Shade
Ich würde ja gern was antworten. Nur kann ich deine Argumente nicht mehr ganz nachvollziehen. Nicht dass sie falsch wären, nur von meinem Standpunkt aus habe ich auch nichts anderes behauptet.Meine Argumente sind Zitate aus dem Standard - mehr nicht.
Bitte interpretiere fuer mich die von mir zitierten Stellen. Fuer mich ist da eigentlich alles klar.
-
groovemaster2002 schrieb:
Das oops gehört für mich dorthin, wo undefiniertes Verhalten in Erscheinung tritt
Wenn also das Programm mit meinem Compiler trotz undefiniertem Verhalten korrekt läuft (es muß ja nicht immer abschmieren), dann gehört nirgends ein oops hin. Wenn ich dann nach 2 Jahren auf die neue Version des Compilers (oder einen andere Compiler) umsteige und da schmiert es ab, dann gehört ein oops hin. Hab ich das so richtig erfaßt?
Macht irgendwie keinen Sinn... aber das tut vieles nicht.MfG Jester
-
@groovemaster
undefiniertes verhalten ist aber undefiniert und muss nicht einmal in erscheinung treten.