Ich stieß auf meinen ersten Compiler, der den an :: delete übergebenen lvalue ändert, aber den lvalue nicht auf Null setzt. Das ist folgendes gilt:Wo im C++ Standard heißt es: :: delete kann lvales ändern?
Foo * p = new Foo();
Foo * q = p;
assert(p != 0);
assert(p == q);
::delete p;
assert(p != q);
assert(p != 0);
Beachten Sie, dass p nicht Null nach dem Löschvorgang ist, und es hat sich geändert von ihm alten Wert. Ein Kollege sagte mir, dass dies nicht ungewöhnlich in seiner Erfahrung mit einigen Mainframe C++ - Compiler, die p zu 0xFFFFFFFF ändern würde, sowie andere Compiler, die p zu 0 ändern würde. Wo im C++ Standard sagt es dass ein Compiler dies tun darf?
durch Stackoverflow Suche, fand ich diese Frage: Why doesn’t delete set the pointer to NULL?, die eine Antwort hatte, die Bjarne Stroustrup's response bezeichnet, dass die Aussage enthält:
C++ explizit erlaubt eine Implementierung der Lösch- einen L-Wert-Operanden auf Null, und ich hatte hoffte, dass Implementierungen das tun würden, aber diese Idee scheint bei Implementierern nicht populär geworden zu sein.
Ich habe Abschnitt 5.3.5 und 12.5 der final committee draft C++0x standard gelesen und gelesen, aber ich sehe nicht den "expliziten" Teil. Sehe ich nur in die falschen Bereiche des Standards? Oder gibt es eine Kette von Logik, die in den Abschnitten ist, aber ich bin nur nicht richtig miteinander verbinden.
Ich habe meine Kopie des Annotated C++ Reference Manual nicht mehr. War es in der ARM, dass ein Compiler das tun konnte?
[Bearbeiten: Korrigieren der Abschnittsreferenz von 3.5.3 bis 5.3.5. Ich füge auch ein interessantes Paradox als Kontrapunkt zu Henks Behauptung hinzu, dass p nach dem Löschen undefiniert ist.]
Es gibt ein interessantes Paradox, wenn p auf Null initialisiert wird.
Foo * p = 0;
Foo * q = p;
assert(p == 0);
assert(p == q);
::delete p;
assert(p == q);
assert(p == 0);
In diesem Fall ist das Verhalten jedoch gut dokumentiert. Wenn delete einen Null-Zeiger erhält, wird angenommen, nichts zu tun, so dass p unverändert bleibt.
Nun, der ARM ist weder hier noch dort. Und lasst uns lvales vergessen. Ist Ihre Frage "Kann löschen sein Argument ändern?". –
Der Standard sagt auch nicht, was ein Compiler tun darf - er gibt nur an, was er tun darf und was nicht. Ich kann in der aktuellen Norm nichts sehen, was verbietet, dass der Zeigerwert geändert wird. –
Ich habe meine Frage nicht als "Kann löschen ändern sein Argument?" weil ich nicht darüber nachdenken wollte, wie eine Klasse, die den Operator deklarieren will, die Änderung ihres Arguments ändert, da sie nur void *, nicht void * & oder void ** akzeptiert. – Ants