Mi sono imbattuto nel mio primo compilatore che cambia il lvalue passato a :: delete, ma non azzera il lvalue. Questo è quanto segue:Dove nel C++ Standard si dice :: delete può cambiare lvalue?
Foo * p = new Foo();
Foo * q = p;
assert(p != 0);
assert(p == q);
::delete p;
assert(p != q);
assert(p != 0);
Si noti che p non è zero dopo l'operazione di cancellazione e che è stato modificato dal vecchio valore. Un collega mi ha detto che questo non è insolito nella sua esperienza avendo lavorato con alcuni compilatori C++ mainframe che avrebbero cambiato p in 0xFFFFFFFF, così come altri compilatori che avrebbero cambiato p a 0.
Dove nello standard C++ dice che un compilatore è autorizzato a fare questo?
La ricerca attraverso StackOverflow, ho trovato questa domanda: Why doesn’t delete set the pointer to NULL? che ha avuto una risposta che di cui Bjarne Stroustrup's response che include l'istruzione:
C++ consente esplicitamente un'implementazione di cancellazione per azzerare un operando lvalue, e ho avuto sperato che le implementazioni lo farebbero, ma quell'idea non sembra essere diventata popolare con gli implementatori.
Ho letto e riletto la sezione 5.3.5 e 12.5 di final committee draft C++0x standard, ma non vedo la parte "esplicita". Sto solo guardando nella parte sbagliata dello standard? O c'è una catena di logica che si trova nelle sezioni, ma io non sto semplicemente collegando correttamente.
Non ho più la mia copia del Manuale di riferimento Annotated C++. Era nel ARM che un compilatore poteva fare questo?
[Modifica: correzione del riferimento di sezione da 3.5.3 a 5.3.5. Aggiungo anche un interessante paradosso come contrappunto all'affermazione di Henk secondo cui p non è definito dopo l'eliminazione.]
C'è un paradosso interessante se p è inizializzato su null.
Foo * p = 0;
Foo * q = p;
assert(p == 0);
assert(p == q);
::delete p;
assert(p == q);
assert(p == 0);
In questo caso, tuttavia, il comportamento è ben documentato. Quando delete ottiene un puntatore nullo, si suppone di non fare nulla, quindi p rimane invariato.
Ebbene, il braccio è né qui né là. E dimentichiamoci di lvalues. La tua domanda "Può cancellare cambiare argomento?". –
Inoltre, lo standard non è grande nel dire cosa è permesso a un compilatore di fare - specifica solo ciò che deve e non deve fare. Non riesco a vedere nulla nello standard corrente che impedisca la modifica del valore del puntatore. –
Non ho espresso la mia domanda come "Può cancellare cambiare argomento?" perché non volevo entrare in una classe che dichiara che l'operatore cancella il supporto cambiando la sua argomentazione dal momento che prende solo void *, non un void * & or void **. – Ants