¿Es seguro #definir NULL nullptr?


He visto la siguiente macro en muchos archivos de encabezado superiores:

#define NULL 0  // C++03

En todo el código, NULL y 0 se usan indistintamente. Si lo cambio a.

#define NULL nullptr  // C++11

¿Causará algún efecto secundario negativo ? Puedo pensar en el único efecto secundario (bueno) ya que el siguiente uso se volverá mal formado;

int i = NULL;
Author: iammilind, 2012-01-25

6 answers

He visto la siguiente macro en el archivo de encabezado superior:

No debería haber visto eso, la biblioteca estándar lo define en <cstddef> (y <stddef.h>). Y, IIRC, de acuerdo con el estándar, redefinir los nombres definidos por los archivos de encabezado estándar resulta en un comportamiento indefinido. Así que desde un punto de vista puramente standard, no deberías hacer eso.


He visto a la gente hacer lo siguiente, por cualquier razón que su mente rota pensó:{[12]]}

struct X{
  virtual void f() = NULL;
}

(Como en [incorrectamente]: "establecer el puntero de la tabla virtual a NULL")

Esto solo es válido si NULL se define como 0, porque = 0 es el token válido para funciones virtuales puras (§9.2 [class.mem]).

Dicho esto, si NULL fue correctamente usado como una constante puntero nulo, entonces nada debería romperse.

Sin embargo, tenga cuidado de que, incluso si aparentemente se usa correctamente, esto cambiará:{[12]]}

void f(int){}
void f(char*){}

f(0); // calls f(int)
f(nullptr); // calls f(char*)

Sin embargo, si ese fue el caso, es casi seguro que se rompió de todos modos.

 39
Author: Xeo,
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
2012-01-25 18:57:04

Mucho mejor es buscar y reemplazar NULL por nullptr en todo el código.

Puede ser sintácticamente seguro, pero ¿dónde pondrías el #define? Crea problemas de organización de código.

 14
Author: spraff,
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
2012-01-25 13:26:36

No. No está permitido (re) definir macros estándar. Y si ves

#define NULL 0

En la parte superior de cualquier archivo que no sea un encabezado estándar (e incluso allí, se debe estar en incluir guardias, y típicamente en guardias adicionales como bueno), entonces ese archivo está roto. Retírela.

Tenga en cuenta que los buenos compiladores típicamente definirán NULL con algo como:

#define NULL __builtin_null

, para acceder a un compilador incorporado que activará una advertencia si es se utiliza en un contexto sin puntero.

 7
Author: James Kanze,
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
2012-01-25 13:42:38

No debería estar definiéndolo en absoluto, a menos que esté escribiendo su propia versión de <cstddef>; ciertamente no debería estar en "muchos archivos de encabezado superiores".

Si está implementando su propia biblioteca estándar, entonces el único requisito es

18.2 / 3 La macro NULL es una constante de puntero nulo de C++ definida por la implementación

Así que 0 o nullptr es aceptable, y nullptr es mejor (si su compilador lo soporta) por la razón que usted da.

 4
Author: Mike Seymour,
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
2012-01-25 13:34:41

Tal Vez No

Si tiene un formato particular de comportamiento de sobrecarga:

void foo(int);
void foo(char*);

Entonces el comportamiento del código:

foo(NULL);

Cambiará dependiendo de si NULL se cambia a nullptr o no.

Por supuesto, hay otra pregunta sobre si es seguro escribir el código que está presente en esta respuesta...

 4
Author: Kaz Dragon,
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
2012-01-25 14:20:02

Si bien podría romper hacia atrás-compatibilidad con material antiguo que estaba mal escrito (ya sea eso, o demasiado inteligente...) , para su código más reciente, esto no es un problema. Debe usar nullptr, y no NULL, donde quiere decir nullptr. Además, debe usar 0 donde quiere decir cero.

 2
Author: Anders Tornblad,
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
2012-01-25 13:29:04