not declared c++ c++11 language-design

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.