¿Puede la macro NULL ser realmente un nullptr?


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

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

Y 21.2.3/2:

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

Sigue 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 añade o resta de un valor de puntero nulo, el resultado es un valor de puntero nulo. Si dos null los valores del puntero se restan, 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 NULL macro no se puede definir realmente como nullptr?

Author: Baum mit Augen, 2018-02-21

4 answers

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

Referencia:

Una constante puntero nulo es un literal entero (5.13.2) con valor cero o un prvalue de tipo std::nullptr_t. Una constante de puntero nulo se puede convertir en un tipo de puntero; el resultado es el valor de puntero nulo de ese tipo y es distinguible de cualquier otro valor de puntero de objeto o tipo de puntero de función. Tal conversión se llama una conversión de puntero nulo. [...]

7.11 / 1 en N4659, enfatizar la mina

Así que NULL puede ser nullptr sin proporcionar los operadores aritméticos.

 46
Author: Baum mit Augen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 14:09:22

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

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

¿Puede la macro NULL ser realmente un nullptr?

Sí, porque nullptr es un puntero nulo literal.

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

 7
Author: user2079303,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 14:53:40

Para la suma, ambos operandos deberán tener un tipo de enumeración aritmética o sin ámbito, o un operando deberá ser un puntero a un tipo de objeto completamente definido y el otro deberá tener un tipo de enumeración integral o sin ámbito.

Para la resta, se llevará a cabo una de las siguientes acciones:
(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 objeto completamente definido tipo; 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 de los dos pueda ser un valor de puntero nulo.

 6
Author: n.m.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 12:13:28

La palabra clave nullptr denota el literal del puntero. 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 de cualquier tipo de puntero a miembro. nullptr en sí mismo no es un valor de puntero ni puntero. Así pues, las operaciones aritméticas no son aplicables a nullptr.

 5
Author: S.M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 10:59:00