sirven que punteros puntero parametros para los funciones declaracion con como arreglos c++ language-lawyer delete-operator incomplete-type nullptr

c++ - que - punteros como parametros de funciones en c



¿Es legal llamar a eliminar en un puntero nulo de un tipo incompleto? (1)

Y si es así, ¿por qué el siguiente código me da la advertencia?

nota: no se llamará al destructor ni a la eliminación del operador específico de la clase, incluso si se declaran cuando se define la clase

?

struct C; int main() { C *c = nullptr; delete c; return 0; }

Entiendo por qué podría ser un comportamiento indefinido en el caso general si C tiene destructores no triviales / virtuales, pero ¿no garantiza / define el estándar que delete en nullptr siempre es un noop sin importar la situación?

Para reiterar: estoy preguntando específicamente sobre el caso donde el puntero a tipo incompleto es nullptr !


El estándar dice ([expr.delete] / 5):

Si el objeto que se está eliminando tiene un tipo de clase incompleto en el punto de eliminación y la clase completa tiene un destructor no trivial o una función de desasignación, el comportamiento no está definido.

Entonces, si T tiene un destructor no trivial o tiene una sobrecarga de operator delete , obtienes UB. No se dice nada acerca de que el UB se base en el valor del puntero (es decir, si es un puntero nulo o no).

¿Qué significa "objeto que se borra"?

Se podría considerar que "objeto que se está eliminando" significa que esta cláusula solo se aplica para delete llamadas en objetos reales. Y por lo tanto, si pasa un puntero nulo, no se aplica.

En primer lugar, el resto de la discusión estándar sobre el comportamiento de la delete indica explícitamente que su comportamiento no se aplica a los punteros nulos. [expr.delete] / 6 & 7 comienzan con "Si el valor del operando de la expresión de eliminación no es un valor de puntero nulo". El párrafo 5 no contiene explícitamente estas palabras. Por lo tanto, debemos asumir que se aplica a los punteros nulos.

Segundo, ¿cuál sería el significado de "objeto que se está eliminando" si se pasara un puntero nulo? Después de todo, no hay "objeto" allí.

Bueno, considere lo que significa interpretar este texto si "objeto que se está eliminando" se refiere específicamente al objeto al final de ese puntero. Bueno, ¿qué sucede si está eliminando una serie de clases incompletas con destructores no triviales?

Por esa lógica, esta cláusula no se aplica , ya sea que el puntero sea nulo o no. ¿Por qué? Porque el "objeto que se elimina" es de un tipo de matriz , no de un tipo de clase. Y por lo tanto, esta cláusula no puede aplicarse. Lo que significa que un compilador debe poder invocar delete[] en una matriz de clases incompletas.

Pero eso es imposible de implementar; requeriría que el compilador pueda rastrear el código que aún no existe.

Por lo tanto, el "objeto que se está eliminando" pretende referirse a std::remove_pointer_t<std::decay_t<decltype(expr)>> , o el estándar requiere un comportamiento que es imposible de implementar. La redacción estándar probablemente podría limpiarse un poco, reemplazando "Si el objeto que se está eliminando tiene un tipo de clase incompleto en el punto de eliminación" con "Si T es un puntero a U o una matriz de U , y U tiene un tipo de clase incompleto en El punto de borrado, ... "