¿Todavía es seguro eliminar nullptr en c++ 0x?
language-lawyer delete-operator (2)
En c++03
es bastante claro que eliminar un puntero nulo no tiene ningún efecto. De hecho, se establece explícitamente en §5.3.5/2
que:
En cualquiera de las alternativas, si el valor del operando de eliminar es el puntero nulo, la operación no tiene efecto.
Sin embargo, en el draft actual para c++0x
parece que falta esta frase. En el resto del borrador, solo pude encontrar frases que establezcan qué sucede si el operando de la expresión de eliminación no es la constante del puntero nulo. Está borrando el puntero nulo aún definido en c++0x
, y si es así, ¿dónde?
Notas:
Hay evidencia circunstancial significativa para sugerir que todavía está bien definido.
Primero, están las dos oraciones en §5.3.5/2
que indican que
En la primera alternativa (eliminar objeto), el valor del operando de eliminación puede ser un valor de puntero nulo, ...
y
En la segunda alternativa (eliminar matriz), el valor del operando de eliminación puede ser un valor de puntero nulo o ...
Dicen que se permite que el operando sea nulo, pero por sí solos no definen realmente qué sucede si es así.
Segundo, cambiar el significado de delete 0
es un gran cambio radical, y el comité de estándares sería muy poco probable que haga este cambio particular. Además, no se menciona que esto sea un cambio radical en el Anexo de Compatibilidad (Anexo C) del borrador c++0x
. El Anexo C es, sin embargo, una sección Informativa, por lo que esto no tiene ninguna incidencia en la interpretación de la norma.
Por otro lado, el hecho de que eliminar el puntero nulo no requiera ningún efecto implica una verificación adicional en tiempo de ejecución. En una gran cantidad de código, el operando nunca puede ser nulo, por lo que esta verificación de tiempo de ejecución entra en conflicto con el principio de cero carga. Tal vez el comité simplemente decidió cambiar el comportamiento para que el c ++ estándar esté más en línea con los objetivos de diseño establecidos del lenguaje.
Por otro lado, el hecho de que eliminar el puntero nulo no requiera ningún efecto implica una verificación adicional en tiempo de ejecución.
La nueva redacción no elimina esa comprobación en tiempo de ejecución para un puntero nulo. A la inversa: el borrador del estándar se acerca aún más a decir que una implementación debe hacer una prueba de puntero nulo para cumplir.
También es digno de mención: el viejo estándar se contradijo al decir (5.3.5 / 2) que "si el valor del operando de eliminación es el puntero nulo, la operación no tiene efecto", pero luego dijo que (5.3.5 / 7) "delete-expression llamará a una función de desasignación". Llamar a una función es un efecto. Esto es particularmente así ya que la función que se llama podría ser una operator delete
anulada.
La nueva redacción elimina esa contradicción, dejando explícitamente a la implementación si se llama a la función de desasignación en el caso de eliminar un puntero nulo.
5.3.5 / 7 dice:
Si el valor del operando de la expresión de eliminación no es un valor de puntero nulo, la expresión de eliminación llamará a una función de desasignación (3.7.4.2). De lo contrario, no se especifica si se llamará a la función de desasignación.
Y 3.7.4.2/3 dice:
El valor del primer argumento proporcionado a una función de desasignación puede ser un valor de puntero nulo; si es así, y si la función de desasignación es una proporcionada en la biblioteca estándar, la llamada no tiene efecto.
Por lo tanto, el comportamiento está bien definido, siempre que se use la función de desasignación estándar, o una función de desasignación proporcionada por el usuario maneje punteros nulos correctamente.