2009-10-13 12 views
7

No estoy seguro de por qué se puede compilar el siguiente código de C++. ¿Por qué una llamada para eliminar el método 0 no produce ningún error?Borrar NULL pero no error de compilación

int *arr = NULL;  // or if I use 0, it's the same thing  
delete arr; 

lo hice tratar de ejecutarlo, y no me dio ningún error en absoluto ...

+4

El código no se compila; necesita un tipo para el puntero (como vacío) y no solo un calificador; esto no es (antiguo) C. –

Respuesta

19

El lenguaje C++ garantías que eliminan p no hará nada si p es igual a NULL.

Para obtener más información, echa un vistazo a la sección 16.8,9 here:

+0

Aún así, la pregunta era por qué el código * compila *; no por qué no hay un error de tiempo de ejecución. – Josh

+5

Es legal en C++ eliminar un puntero NULL, por lo tanto, el compilador está de acuerdo con él. –

+0

¿Es legal desreferencia nulo también? ¿Qué tal desbordar la pila? Muéstrame un compilador que se equivoque en esas condiciones ... – Josh

0

NULL y 0 no son la misma cosa. En C++ debe usar 0.

No hay nada sintácticamente incorrecto o ambiguo sobre la eliminación del puntero nulo. De hecho, esto es por definición un no-op; es decir, la operación de eliminar la dirección 0 es equivalente a no hacer nada en absoluto.

+6

En realidad, en C++, NULL se define como 0. Además, NULL vs. 0 es un debate estilístico para el que no hay una respuesta clara. – rlbond

+2

No hay absolutamente ninguna razón para preferir 0 sobre NULL en C++. Aunque, por alguna razón, la recomendación de "usar 0 en C++" aparece aquí y allá de vez en cuando. No sé de dónde se origina esta leyenda urbana, pero, una vez más, no hay absolutamente nada de malo con el uso de NULL en C++ y, en general, en aras de la legibilidad, NULL es preferible a 0. – AnT

+1

Stroustrup prefiere 0 en lugar de NULL: http : //www.research.att.com/~bs/bs_faq2.html # null – ChrisW

0

Aunque su ejemplo es trivial, no hay forma de que un compilador sepa (en tiempo de compilación) el valor de un puntero.

Puede también eliminar la referencia nula en tiempo de compilación:

// this code compiles 
Object* pObject = 0; 
pObject->SomeMethod(); 

compiladores no están construidos para manejar este tipo de situaciones de error en tiempo de compilación.

Y la mayoría de las implementaciones (¿todas?) Tienen 'eliminar 0' como no operativas. Este código debe funcionar correctamente:

Object* pObject = new Object(); 
delete pObject; 
pObject = 0; 
delete pObject; 

Aunque no estoy 100% seguro de que :)

+3

No creo que eliminar null sea un error en tiempo de ejecución. – Jacob

+0

Tienes razón. Me he encontrado con problemas de borrado doble, ¿o quizás estoy imaginando cosas? – Josh

+4

Cualquier compilador de C++ que trate "eliminar NULL" como cualquier cosa que no sea una operación no operativa es un compilador con errores. El lenguaje C++ especifica que eliminar un puntero NULL es seguro. (Llamar a eliminar dos veces en el mismo puntero que no sea NULL, por otro lado, te meterá en problemas) –

1

Puede eliminar un puntero NULL sin problema, y ​​el error es posible que/puede tener no será en tiempo de compilación, pero en tiempo de ejecución.

int *ptr_A = &a; 
ptr_A = NULL; 
delete ptr_A; 

Por lo general, es conveniente hacerlo:

... 
delete ptr; 
ptr = NULL; 
+1

Por lo general, es una mala práctica anotar un puntero. La razón es que los punteros deben estar encapsulados en clases. 'delete' aparece en los destructores, después de lo cual el puntero ni siquiera existe o en la asignación, en la que el puntero obtiene un nuevo valor. Por lo tanto, generalmente no hay métodos que establezcan el puntero a NULL. La única excepción obvia es una parte "opcional" de un objeto que ya no se necesita, pero considere 'boost :: optional ' para eso. – MSalters

1

Es un estándar de facto en lenguajes C y C++ (y no sólo en ellos) que las rutinas desasignación de recursos deben aceptar los argumentos nula-puntero y simplemente no hagas nada. En realidad, es una convención bastante convencional. Entonces, la verdadera pregunta aquí: ¿por qué te sorprende? ¿Qué te hace pensar que debería producir un error? Por otra parte, ¿qué te hace pensar que no debería compilar ???

Por cierto, su pregunta, la forma en que se indica, no parece tener mucho sentido, ya que su código no se puede compilar. La supuesta declaración de puntero carece de un tipo, lo que hará que cualquier compilador emita un mensaje de diagnóstico.

+3

s/de-facto/de jure/- vea la cita de la norma ISO. – MSalters

Cuestiones relacionadas