2009-12-22 13 views
8
#ifndef NULL 
#define NULL NULL 
#endif 

Este código se compila en gcc sin advertencias/errores. ¿Puede alguien explicar qué está haciendo el preprocesador aquí?#define NULL NULL

+1

NULL no significa indefinido en C/C++ ... – Artelius

+3

Probablemente sea mejor que #define SIXTY_NINE 69. http://bugpwr.blogspot.com/2007/07/magic-numbers-in-code.html –

+0

try hacer: #ifndef NULL #define NULL 0 #endif – TripleS

Respuesta

19

cualquier lugar del compilador ve el texto "NULO" lo reemplazará con el texto "NULO". Es como hacer una búsqueda y reemplazo en su código para "NULO" y reemplazarlo por "NULO". No es ilegal, simplemente raro :)

+6

Creo que es importante tener en cuenta que es casi seguro que no lo hará a menos que NULL no esté definido. NULL generalmente se define, por lo que este bloque probablemente no haga nada. – Adam

5

Es normal:

#ifndef JON_SKEET 
#define JON_SKEET JON_SKEET 
#endif 

Esto compila también. Esto se debe a que el preprocesador simplemente reemplaza sin sentido. Lo que reemplaza y lo que reemplaza no necesita ser identificadores válidos.

Piénselo de esta manera: abra la búsqueda de su editor & Reemplace la ventana y escriba "NULO" en los campos Replace y Replace with. No dará ningún error o advertencia y "funcionará", aunque en realidad no haga nada. El preprocesador hace lo mismo.

Obviamente cuando intenta utilizarlo:

 
'JON_SKEET' undeclared (first use in this function) 
(Each undeclared identifier is reported only once 
for each function it appears in.) 
+0

Sí, pero bloques como ese generalmente implican que * el hecho de que el símbolo está definido * es lo que importa. Es bastante extraño estar haciendo eso para NULL. – Aaronaught

+0

No realmente, no es un requisito. –

0

¿no define simplemente NULL como la secuencia de caracteres "NULL"?

+1

No. Sería '#define NULL" NULL "' –

+2

Tenga cuidado cuando diga secuencia de caracteres y use comillas, ya que podría parecer que se está refiriendo a una matriz de caracteres c-string '" NULL "'. – catchmeifyoutry

+0

lo era, porque la pregunta era ... – dicroce

2

Claramente esto no se está utilizando como una macro, se está utilizando como un indicador de compilación. ¿Hay otras áreas del código donde vea #ifdef NULL o #ifndef NULL?

Es muy extraño usar "NULO", específicamente, como tal bandera, pero he visto extraño (#define TRUE FALSE) ...

14

La única razón posible para hacer esto sería hacer que antes incluyendo ficheros de cabecera que a su vez hacer algo como

#ifndef NULL 
#define NULL (void *)0 
#endif 

Esto entonces detener el NULL de ser definido por el estilo.

+8

Señor, apruebo su avatar. No he pensado en Lemmings en mucho tiempo. –

+0

¿No acaba de plantear la pregunta aún más misteriosa de por qué querría evitar que NULL se defina en algún otro encabezado? – Aaronaught

+0

Bueno, me gana :) – Artelius

1

En respuesta a la pregunta de cuál es el preprocesador está haciendo:

A menos que haya precedentes código que undefs NULL, es saltarse la #define NULL NULL por completo. NULL casi seguramente ya está definido. En C++, se prefiere el uso de 0 debido a la comprobación de tipos más ajustada de C++. Si debe usar NULL, lo mejor es declarar const int NULL = 0; (consulte la Sección 5.1.1 de Stroustrup).

3

He visto casos en los que un código como este trae un valor del espacio de nombres del compilador ("espacio de nombres" en general, no C++ namespace) al espacio de nombres del preprocesador, , p.:

// In the compiler namespace, not in the preprocessor namespace 
static int const FOO = 1234; 

// Bring the constant into the preprocessor namespace as well 
#ifndef FOO  // <---- FOO really is undefined here. 
#define FOO FOO 
#endif 

Cosas realmente feas.

Personalmente no he encontrado un uso para este tipo de cosas, pero existe no obstante.


EDITAR: Mientras que he visto esto, no sé por qué sería útil, aparte de comprobar si "FOO" definido como un símbolo de preprocesador en otro lugar en el código; quizás al tratar con algún código heredado. ¿Nadie?

+0

Hmm, pensé que tenía un uso allí para un momento, pero luego me di cuenta de que estaba mal. Si FOO ya está definido, entonces habrá sido reemplazado en la línea 'static int const FOO = 1234;'. No tengo idea de por qué estarías preparado para continuar bajo esas condiciones. '#define FOO FOO' potencialmente tiene sentido, como dices, si estás reemplazando una macro con una constante pero no quieres cambiar un código viejo que verifica que esté definido. Pero dejar que FOO se defina a otra cosa cuando se define constante FOO me parece un problema. –

+0

@Steve: De acuerdo. Tal código es ciertamente hinky. – Void