¿Se permite eliminar para modificar su parámetro?

En una respuestahttps://stackoverflow.com/a/704568/8157187, hay una cita de Stroustrup:

C ++ permite explícitamente una implementación de eliminar para poner a cero un operando lvalue, y esperaba que las implementaciones hicieran eso, pero esa idea no parece haberse popularizado entre los implementadores.

Sin embargo, no pude encontrar esta declaración explícita en el estándar. Hay una parte del proyecto de norma actual (N4659), que se puede interpretar de esta manera:

6.7:

Cuando se alcanza el final de la duración de una región de almacenamiento, los valores de todos los punteros que representan la dirección de cualquier parte de esa región de almacenamiento se convierten en valores de puntero no válidos (6.9.2). La indirección a través de un valor de puntero no válido y el paso de un valor de puntero no válido a una función de desasignación tienen un comportamiento indefinido. Cualquier otro uso de un valor de puntero no válido tiene un comportamiento definido por la implementación.

Nota al pie: algunas implementaciones pueden definir que copiar un valor de puntero no válido provoca un error de tiempo de ejecución generado por el sistema

Entonces, después de undelete ptr;, ptrEl valor de se convierte en un valor de puntero no válido, y el uso de este valor tiene un comportamiento definido por la implementación. Sin embargo, no dice queptrEl valor de 'está permitido cambiar.

Puede ser una pregunta filosófica, ¿cómo se puede decidir que un valor ha cambiado, si no se puede usar su valor?

6.9:

Para cualquier objeto (que no sea un subobjeto de clase base) de tipo T copiable trivialmente, ya sea que el objeto tenga o no un valor válido de tipo T, los bytes subyacentes (4.4) que componen el objeto se pueden copiar en una matriz de caracteres, unsigned char, o std :: byte (21.2.1) .43 Si el contenido de esa matriz se copia de nuevo en el objeto, el objeto posteriormente mantendrá su valor original.

Entonces, parece que es válido paramemcpy un valor de puntero no válido en una matriz de caracteres (dependiendo de qué enunciado sea "más fuerte", 6.7 o 6.9. Para mí, 6.9 parece más fuerte).

De esta manera, puedo detectar que el valor del puntero ha cambiado pordelete: memcpy el valor del puntero antes y después deldelete a la matriz de caracteres, luego compárelos.

Entonces, según tengo entendido, 6.7 no garantiza quedelete se le permite modificar su parámetro.

¿Se permite eliminar para modificar su parámetro?

Mira los comentarios aquí:https://stackoverflow.com/a/45142972/8157187

Aquí hay un código del mundo real poco probable, pero aún posible, donde esto importa:

SomeObject *o = ...; // We have a SomeObject
// This SomeObject is registered into someHashtable, with its memory address
// The hashtable interface is C-like, it handles opaque keys (variable length unsigned char arrays)

delete o;

unsigned char key[sizeof(o)];
memcpy(key, &o, sizeof(o)); // Is this line OK? Is its behavior implementation defined?
someHashtable.remove(key, sizeof(key)); // Remove o from the hashtable

Por supuesto, este fragmento se puede reordenar, por lo que se convierte en un código seguramente válido. Pero la pregunta es: ¿es este un código válido?

Aquí hay un tren de pensamiento relacionado: supongamos que una implementación define lo que describe la nota al pie de página:

copiar un valor de puntero no válido provoca un error de tiempo de ejecución generado por el sistema

6.9 garantiza que puedomemcpy() algún valor. Incluso uno inválido. Entonces, en esta implementación teórica, cuando yomemcpy() el valor de puntero no válido (que debería tener éxito, 6.9 garantiza que), en cierto sentido, no uso el valor de puntero no válido, sino solo sus bytes subyacentes (porque generaría un error de tiempo de ejecución y 6.9 no lo permite) ,entonces 6.7 no aplica.

Respuestas a la pregunta(5)

Su respuesta a la pregunta