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
NULLes 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
0se 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 valor0convertido 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.