c++ null language-lawyer nullptr

c++ - ¿Puede la macro NULL realmente ser un nullptr?



language-lawyer (4)

Según el borrador de la norma N4713 (7.11 / 1):

Una constante de puntero nula es un literal entero (5.13.2) con valor cero o un prvalor de tipo std::nullptr_t .

y 21.2.3 / 2:

La macro NULL es una constante de puntero nulo definida por la implementación.

siga que NULL se puede definir como nullptr . Lo mismo se menciona en cppreference :

#define NULL 0 //since C++11 #define NULL nullptr

Al mismo tiempo, la cláusula "Operadores aditivos" dice (8.5.6 / 7):

Si el valor 0 se agrega o se resta de un valor de puntero nulo, el resultado es un valor de puntero nulo. Si se restan dos valores de puntero nulo, el resultado se compara igual al valor 0 convertido al tipo std::ptrdiff_t .

Por lo tanto, el siguiente código debe ser válido:

0 + nullptr; nullptr - nullptr;

pero debido a la falta de operadores +/- para std::nullptr_t el código no es válido .

¿Hay algo que no tomé en cuenta o la macro NULL no se puede definir realmente como nullptr ?


Además, ambos operandos tendrán un tipo de enumeración aritmética o sin ámbito, o un operando será un puntero a un tipo de objeto completamente definido y el otro tendrá un tipo de enumeración integral o sin ámbito.

Para la resta, uno de los siguientes deberá contener:
(2.1) ambos operandos tienen un tipo de enumeración aritmética o sin ámbito; o
(2.2) ambos operandos son punteros a versiones cv calificadas o cv no calificadas del mismo tipo de objeto completamente definido; o
(2.3) el operando izquierdo es un puntero a un tipo de objeto completamente definido y el operando derecho tiene un tipo de enumeración integral o sin ámbito.

std::nullptr_t no es ninguno de ellos, por lo tanto, std::nullptr no puede participar en operaciones aditivas.

Tenga en cuenta que ni siquiera todos los valores de puntero pueden participar. Por ejemplo, los valores de puntero de función y los valores de puntero nulo no pueden, aunque cualquiera puede ser un valor de puntero nulo.


La palabra clave nullptr denota el puntero literal. Es un prvalue de tipo std::nullptr_t . Existen conversiones implícitas de nullptr a valor de puntero nulo de cualquier tipo de puntero y cualquier puntero a tipo de miembro. nullptr sí no es un valor de puntero ni un puntero. Por lo tanto, las operaciones aritméticas no son aplicables a nullptr .


Si bien nullptr es una constante de puntero nulo, no es un valor de puntero nulo. Este último es un valor de algún tipo de puntero, que no es std::nullptr_t .

Referencia:

Una constante de puntero nula es un literal entero (5.13.2) con valor cero o un prvalor de tipo std::nullptr_t . Una constante de puntero nula se puede convertir en un tipo de puntero; el resultado es el valor de puntero nulo de ese tipo y se distingue de cualquier otro valor del puntero de objeto o del tipo de puntero de función. Dicha conversión se denomina conversión de puntero nulo. [...]

7.11 / 1 en N4659, enfatiza el mio

Por lo tanto, NULL puede ser nullptr sin proporcionar los operadores aritméticos.


nullptr es un literal de puntero nulo, y aunque el resultado de convertir nullptr a un tipo de puntero es el valor del puntero nulo, nullptr sí no es de tipo puntero, sino de tipo std::nullptr_t . La aritmética funciona si convierte nullptr a un tipo de puntero:

0 + (int*)nullptr; (int*)nullptr - (int*)nullptr;

¿Puede la macro NULL realmente ser un nullptr?

Sí, porque nullptr es un puntero literal nulo.

Tenga en cuenta que antes de C ++ 11, todos los literales de puntero nulo en C ++ también eran literales enteros, por lo que este código incorrecto: char c = NULL; Solía ​​trabajar en la práctica. Si NULL se define como nullptr , ese código ya no funciona.