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 valor0
convertido al tipostd::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.