Wo im C ++ Standard heißt es: :: delete kann lvales ändern?

8

Ich stieß auf meinen ersten Compiler, der den an :: delete übergebenen lvalue ändert, aber den lvalue nicht auf Null setzt. Das ist das Folgende:

%Vor%

Beachten Sie, dass p nach dem Löschvorgang nicht null ist und sich von seinem alten Wert geändert hat. Ein Kollege sagte mir, dass dies nicht ungewöhnlich sei, nachdem er mit einigen C ++ - Compilern von Mainframe gearbeitet habe, die p in 0xFFFFFFFF geändert hätten, sowie mit anderen Compilern, die p in 0 änderten.

Wo heißt es im C ++ Standard, dass ein Compiler dies tun darf?

Beim Durchsuchen von StackOverflow habe ich folgende Frage gefunden: Warum nicht Löschen setzte den Zeiger auf NULL? , der eine Antwort auf Bjarne Stroustrups Antwort hatte , die die Aussage enthält:

  

C ++ erlaubt explizit eine Implementierung von delete, um einen Lvalue-Operanden auf Null zu setzen, und ich hatte gehofft, 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 Entwurf C ++ 0x Standard , aber ich sehe nicht den" expliziten "Teil. Sehe ich nur in die falschen Bereiche des Standards? Oder gibt es eine Logikkette, die in den Abschnitten steht, aber ich verbinde einfach nicht richtig miteinander.

Ich habe meine Kopie des Annotated C ++ Reference Manual nicht mehr. War es in der ARM, dass ein Compiler das tun könnte?

[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.

%Vor%

In diesem Fall ist das Verhalten jedoch gut dokumentiert. Wenn delete einen Null-Zeiger erhält, soll nichts unternommen werden, also bleibt p unverändert.

    
Ants 02.08.2010, 20:06
quelle

1 Antwort

8

Es ist vielleicht nicht so explizit. In 5.3.5 / 7 heißt es, dass der Ausdruck delete eine Deallocator-Funktion aufruft. Dann heißt es in 3.7.3.2/4, dass die Verwendung eines nicht zugeordneten Zeigers undefiniert ist. Da der Wert des Zeigers nach der Freigabe nicht mehr verwendet werden kann, macht es keinen Unterschied, ob der Zeiger den Wert beibehält oder der Wert von der Implementierung geändert wird.

5.3.5 / 7

  

Der delete-expression ruft eine Funktion zum Aufheben der Zuweisung auf (3.7.3.2).

3.7.3.2/4

  

Wenn das Argument einer Deallokationsfunktion in der Standardbibliothek ein Zeiger ist, der nicht der Nullzeigerwert ist (4.10), soll die Deallokationsfunktion den vom Zeiger referenzierten Speicher freigeben und alle Zeiger, die sich auf einen beziehen, ungültig machen Teil des freigegebenen Speichers. Die Verwendung eines ungültigen Zeigerwerts (einschließlich der Übergabe an eine Zuordnungsfunktion) ist nicht definiert. .

Die Referenzen stammen aus dem aktuellen Standard. In der kommenden Norm 5.3.5 / 7 wurde neu formuliert:

C ++ 0x FD 5.3.5 / 7

  

Wenn der Wert des Operanden des Löschausdrucks kein Nullzeigerwert ist, ruft der Löschausdruck eine Aufteilungsfunktion (3.7.4.2) auf. Ansonsten ist nicht angegeben, ob die Freigabe-Funktion aufgerufen wird. [Hinweis: Die Funktion zum Aufheben der Zuweisung wird unabhängig davon aufgerufen, ob der Destruktor für das Objekt oder ein Element des Arrays eine Ausnahme auslöst. - Endnote]

    
David Rodríguez - dribeas 02.08.2010, 22:05
quelle