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

Ten kod jest kompilowany w gcc bez ostrzeżeń/błędów. Czy ktoś może wyjaśnić, co robi preprocesor?#define NULL NULL

+1

NULL nie oznacza niezdefiniowanego w C/C++ ... – Artelius

+3

Prawdopodobnie bije #define SIXTY_NINE 69. http://bugpwr.blogspot.com/2007/07/magic-numbers-in-code.html –

+0

try do wykonania: #ifndef NULL #define NULL 0 #endif – TripleS

Odpowiedz

19

Gdziekolwiek kompilator widzi tekst „null” będzie zastąpienie go tekstem „null”. To jest jak robienie wyszukiwania i zamiany w kodzie dla "NULL" i zastępowanie "NULL". Nie jest nielegalne, tylko dziwne :)

+6

Myślę, że ważne jest, aby zauważyć, że prawie na pewno nie rób tego, chyba że NULL nie jest zdefiniowane. Wartość NULL jest zwykle definiowana, więc ten blok prawdopodobnie nic nie robi. – Adam

5

To normalne:

#ifndef JON_SKEET 
#define JON_SKEET JON_SKEET 
#endif 

ten zestawia też. Dzieje się tak dlatego, że preprocesor po prostu zastępuje bezmyślne zastępstwo. To, co zastępuje i co zastępuje, nie musi być poprawnymi identyfikatorami.

Pomyśl o tym w następujący sposób: otwórz okno edytora Szukaj & Zamień okno i wpisz "NULL" w polach Replace i Replace with. Nie da żadnego błędu ani ostrzeżenia i "zadziała", mimo że w rzeczywistości nic nie robi. Preprocesor robi to samo.

Oczywiście podczas próby użycia:

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

Tak, ale takie bloki zasadniczo oznaczają, że znaczenie ma fakt, że symbol jest zdefiniowany *. Dość dziwne, że robię to dla NULL. – Aaronaught

+0

Niezupełnie, to nie jest wymagane. –

0

Czy to nie definiuje NULL jako sekwencji znaków "NULL"?

+1

Nie. To byłoby '#define NULL" NULL "' –

+2

Uważaj, kiedy wypowiadasz sekwencję znaków i używasz cudzysłowów, ponieważ może się wydawać, że odwołujesz się do tablicy znaków c-string '" NULL "'. – catchmeifyoutry

+0

był, ponieważ pytanie było ... – dicroce

2

Oczywiście nie jest to używane jako makro, jest używane jako flaga kompilacji. Czy są inne obszary kodu, w których widać #ifdef NULL lub #ifndef NULL?

To jest bardzo dziwne w użyciu „null”, w szczególności, jako takiej flagi, ale widziałem obcego (#define TRUE FALSE) ...

14

Jedynym możliwym powodem robi to byłoby to zrobić przed tym plików nagłówkowych, które same coś zrobić jak

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

byłoby wtedy zatrzymać NULL przed zdefiniowane tak.

+8

Sir, aprobuję twój awatar. Od dawna nie myślałem o Lemmingach. –

+0

Czy to nie tylko jeszcze bardziej tajemnicze pytanie, dlaczego nie chcesz, aby NULL został zdefiniowany w innym nagłówku? – Aaronaught

+0

Dobrze, bije mnie :) – Artelius

1

W odpowiedzi na pytanie o to, co robi preprocesora:

Chyba że kod, który undefs NULL poprzedzający, to omijając #define NULL NULL całkowicie. NULL jest prawie na pewno już zdefiniowany. W języku C++ preferowane jest użycie wartości 0 z powodu ściślejszego sprawdzania typów w C++. Jeśli musisz używać wartości NULL, najlepiej jest zadeklarować const int NULL = 0; (patrz sekcja 5.1.1 programu Stroustrup).

3

Widziałem przypadki, w których kod taki przynosi wartość z przestrzeni nazw kompilatora (ogólnie "przestrzeń nazw", a nie C++ namespace) do przestrzeni nazw preprocesora, np. , np.:

// 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 

Naprawdę brzydkie rzeczy.

Osobiście nie znalazłem żadnego zastosowania dla tego rodzaju rzeczy, ale mimo to istnieje.


EDIT: A ja widziałem to, nie wiem, dlaczego to byłoby przydatne, inne niż sprawdzić, czy „FOO” zdefiniowano jako symbol preprocesora gdzieś w kodzie; być może w radzeniu sobie z jakimś starszym kodem. Ktoś?

+0

Hmm, myślałem, że mam tam zastosowanie przez chwilę, ale potem zdałem sobie sprawę, że to było złe. Jeśli FOO jest już zdefiniowany, to zostanie on zastąpiony w wierszu 'static int const FOO = 1234;'. Nie mam pojęcia, dlaczego byłbyś gotowy do kontynuowania w tych warunkach. '#define FOO FOO' ma potencjalnie sens, jak mówisz, jeśli zastępujesz makro stałą, ale nie chcesz zmieniać jakiegoś starego kodu, który sprawdza, czy jest on zdefiniowany. Ale pozwalanie FOO na zdefiniowanie czegoś innego, gdy definiujesz ciągłe FOO, brzmi dla mnie jak kłopot. –

+0

@Steve: Zgoda. Taki kod jest z pewnością obłędny. – Void

Powiązane problemy