c++ - declared - ¿Por qué no llamar a nullptr NULL?
nullptr c++ (7)
¿Por qué el comité de estándares decidió no llamar al nuevo puntero nulo constante
NULL
Presumiblemente porque el nuevo puntero nulo es una palabra clave, y las palabras clave no pueden ser
#defined
, por lo que llamarlo
NULL
habría hecho que la inclusión de cualquier encabezado C probablemente esté mal formada.
o declarar que
NULL
debe
#defined
a
nullptr
?
El comité de estándares permite que
NULL
sea
#defined
a
nullptr
, pero no lo requiere.
C ++ 11 18.2 Tipos [support.types] / 2 : La macro
NULL
es una constante de puntero nulo C ++ definida por la implementación en esta Norma Internacional.C ++ 11 4.10 Conversiones de puntero [conv.ptr] / 1 : Una constante de puntero nulo es un valor de expresión constante integral (5.19) de tipo entero que se evalúa a cero o un valor de tipo
std::nullptr_t
.
La compatibilidad con versiones anteriores no es una preocupación aquí, cualquier uso de
NULL
que suponga que es una forma del entero
0
no es conforme estándar.
Las implementaciones pueden optar por no hacerlo para condonar este tipo de comportamiento malvado.
En C ++ 11, la palabra clave
nullptr
se agregó como una constante de puntero nulo más segura, ya que la definición común anterior de
NULL
como 0 tiene algunos problemas.
¿Por qué el comité de estándares decidió no llamar al nuevo puntero nulo constante
NULL
, o declarar que
NULL
debería ser
#define
d to
nullptr
?
Demostraré un caso donde la decisión de definir nullptr como un tipo diferente ayuda a prevenir errores.
Considere estas funciones:
void foo(int);
void foo(char *);
int main()
{
foo(NULL); // oops
}
En C ++ 98, el código anterior llama a la función foo (int), porque NULL se reemplaza por 0, que probablemente no sea lo que pretendía.
Pero si llamas a foo (nullptr) , llama al correcto - foo (char *) .
El
nullptr
se introduce por seguridad de tipo y por claridad (probablemente para detener la inicialización de tipos sin puntero usando
NULL
).
El
NULL
(tipo int) no se cambia a
nullptr
(tipo puntero) para evitar confusiones y garantizar la compatibilidad con versiones anteriores.
Por lo tanto, el tren de pensamiento estándar del comité probablemente esté relacionado con una transición fluida de la notación antigua a la nueva sin causar ambigüedades ni frenar ningún código ya existente.
Sin realmente sentarse en la discusión en el comité de estándares, es difícil decirlo con certeza, pero creo que porque rompería algún código que usa
NULL
en un significado donde
nullptr
no es lo suficientemente compatible.
Y romper el viejo código nunca es una buena idea.
Stephan T. Lavavej (miembro del comité estándar de C ++) explicó que una vez en una talk (55:35):
Si bien se permite una implementación para
#define NULL nullptr
, rompería algunos usos como
int i = NULL;
y aparentemente hay muchos de esos. Entonces no pudieron forzar el cambio.
NULL
no es de tipo seguro.
Por razones históricas, se definió como 0 sin conversión, y el compilador silencia la advertencia del número de conversión al puntero en este cero especial.
Por instante, puedes hacer:
void* p = 0;
pero no esto sin un casting implícito:
void* p = 1234;
El efecto secundario es que se puede abusar como valores numéricos, como se menciona en otra respuesta.
nullptr
mejora esto haciendo cumplir que sea un puntero, no puede asignar esto a un número entero.
Como se cambia el comportamiento, se crea un nuevo nombre para la compatibilidad con versiones anteriores.
También tenga en cuenta que,
nullptr
es manejado por el compilador, su valor real no está expuesto al usuario (como cero en caso de
NULL
).
Es mucho más fácil tener un valor dependiente de la arquitectura, digamos
0xdeadbeef
, sin afectar la lógica del código del programador.
nullptr
es de
tipo puntero
, mientras que
NULL
tiende a ser entero y, a veces, en funciones sobrecargadas, debe ser claro que está utilizando un puntero y no un entero; esto es cuando
nullptr
es útil.
Entonces, para responder realmente a su pregunta,
NULL
y
nullptr
sirven para dos propósitos diferentes y redefinir uno a otro probablemente romperá muchas cosas en bases de código ya existentes.
Además de eso, verifique esto desde el sitio web de Bjarne Stroustrup :
¿Debo usar NULL o 0?
En C ++, la definición de NULL es 0, por lo que solo hay una diferencia estética. Prefiero evitar las macros, así que uso 0. Otro problema con NULL es que las personas a veces creen erróneamente que es diferente de 0 y / o no un número entero. En el código pre-estándar, NULL fue / a veces se define como algo inadecuado y, por lo tanto, tuvo / debe evitarse. Eso es menos común en estos días. Si tiene que nombrar el puntero nulo, llámelo nullptr; así se llama en C ++ 11. Entonces, "nullptr" será una palabra clave.