#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
#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
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 :)
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
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.)
Tak, ale takie bloki zasadniczo oznaczają, że znaczenie ma fakt, że symbol jest zdefiniowany *. Dość dziwne, że robię to dla NULL. – Aaronaught
Niezupełnie, to nie jest wymagane. –
Czy to nie definiuje NULL jako sekwencji znaków "NULL"?
Nie. To byłoby '#define NULL" NULL "' –
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
był, ponieważ pytanie było ... – dicroce
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
) ...
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.
Sir, aprobuję twój awatar. Od dawna nie myślałem o Lemmingach. –
Czy to nie tylko jeszcze bardziej tajemnicze pytanie, dlaczego nie chcesz, aby NULL został zdefiniowany w innym nagłówku? – Aaronaught
Dobrze, bije mnie :) – Artelius
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).
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ś?
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. –
@Steve: Zgoda. Taki kod jest z pewnością obłędny. – Void
NULL nie oznacza niezdefiniowanego w C/C++ ... – Artelius
Prawdopodobnie bije #define SIXTY_NINE 69. http://bugpwr.blogspot.com/2007/07/magic-numbers-in-code.html –
try do wykonania: #ifndef NULL #define NULL 0 #endif – TripleS