WhozCraig napisał te komentarze do usuniętego już answer, ale może być promowany do pełnej odpowiedzi (i to właśnie tutaj zrobiłem). Zauważa:
Ciekawa uwaga: AS/400 jest bardzo wyjątkowa platforma, gdzie każdy nie- ważny wskaźnik jest uważane za równoważne NULL
. Mechanika, którą stosują, aby to zrobić, jest po prostu niesamowita. "Ważny" w tym sensie jest dowolny 128-bitowy wskaźnik (platforma wykorzystuje 128-bitową liniową przestrzeń adresową dla wszystkiego) zawierającą "wartość" uzyskaną przez znany zaufany zbiór instrukcji. Trudno uwierzyć, int *p = (int *)1; if (p) { printf("foo"); }
będzie nie wydrukuj "foo" na tej platformie. Wartość przypisana do p nie jest zaufana źródłowo, a zatem jest uznawana za "nieważną" i tym samym równoważną NULL
.
To zadziwiające, jak to działa. Każdy 16-bajtowy akapit w zmapowanej wirtualnej przestrzeni adresowej procesu ma odpowiadający "bit" w bitmapie obejmującym cały proces. Wszystkie wskaźniki muszą znajdować się na jednej z tych granic akapitu. Jeśli bit jest "zapalony", odpowiedni wskaźnik został zapisany z zaufanego źródła, w przeciwnym razie jest nieważny i odpowiada NULL. Połączenia do malloc, wskaźnik matematyki, itp., Są badane w celu ustalenia, czy ten kawałek się świeci, czy nie. I jak można sobie wyobrazić, umieszczanie wskaźników w strukturach przynosi zupełnie nowy świat bolesnej idei pakowania konstrukcji.
ta jest oznaczona społeczności Wiki (to nie moja odpowiedź - Nie powinien dostać kredyt), ale można je usunąć, jeśli WhozCraig pisze swoją własną odpowiedź.
To pokazuje, że istnieją prawdziwe platformy o ciekawych właściwościach wskaźnika.
Istnieją platformy, gdzie #define NULL ((void *)0)
nie jest zwyczajową definicją; na niektórych platformach może to być tylko 0
, na innych, 0L
lub 0ULL
lub inne odpowiednie wartości, o ile kompilator je rozumie. C++ nie podoba się jako ((void *)0)
jako definicja; systemy, w których nagłówki współdziałające z C++ mogą nie używać wersji void indicator.
Nauczyłem się C na komputerze, gdzie reprezentacja dla adresu char *
dla danej lokalizacji pamięci była inna niż adres int *
dla tej samej lokalizacji pamięci. Było to w czasach poprzedzających void *
, ale oznaczało to, że trzeba było poprawnie zadeklarować malloc()
(char *malloc();
- również bez prototypów), a musieliście jawnie rzucić zwracaną wartość do poprawnego typu lub otrzymaliście zrzut główny. Bądź wdzięczny za standard C (choć przedmiotowa maszyna, ICL Perq - badged hardware z Three Rivers - została w dużej mierze zastąpiona przez czas zdefiniowania standardu).
Możesz użyć '0' zamiast' NULL'. – pmg
NULL jest zdefiniowane w 'stddef.h', nie musisz sam go definiować. – Mat
@pmg 0 nie jest przenośny, jeśli odpowiedź na moje pierwsze pytanie jest prawdziwa – stdcall