2010-04-02 10 views
5

Linuksa stddef.h definiuje offsetof() jak:Dlaczego odjąć pusty wskaźnik w offsetof()?

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 

natomiast artykuł na offsetof() (http://en.wikipedia.org/wiki/Offsetof) określa ją jako:

#define offsetof(st, m) \ 
    ((size_t) ((char *)&((st *)(0))->m - (char *)0)) 

Dlaczego odjąć (char *)0 w wersji Wikipedii? Czy jest jakikolwiek przypadek, w którym miałoby to znaczenie?

+0

Nie powinieneś używać/badać kodu, który może wywoływać niezdefiniowane zachowanie, jak wyżej. Implementacja może wykorzystywać takie skandaliczne hacki, ponieważ wie, jakie rodzaje niezdefiniowanych zachowań potajemnie działają. Ale to, co "potajemnie działa", nie jest całkowicie przenośne. – CTMacUser

Odpowiedz

6

Pierwsza wersja konwertuje wskaźnik do liczby całkowitej z obsadą, który nie jest przenośny.

Druga wersja jest bardziej przenośna dla szerszej gamy kompilatorów, ponieważ opiera się na arytmetyzacji wskaźnika przez kompilator, aby uzyskać wynik całkowity zamiast typecast.

BTW, byłem edytorem, który dodał oryginalny kod do wpisu Wiki, który był linuksowy. Późniejsi edytorzy zmienili go na bardziej przenośną wersję.

+0

Dzięki za odpowiedź. Pytanie uzupełniające "Czy (size_t) ((char *) 0) nigdy nie zostanie ocenione na 0?" opublikowane na http://stackoverflow.com/questions/2581522/does-size-tchar-0-ever-not-evaluate-to-0 –

+0

Interesujące - ale jest to drugie wyrażenie naprawdę bardziej przenośne, ponieważ wskaźnik arytmetyczny na wskaźnikach zerowych jest niezdefiniowany? –

+1

Jest bardziej przenośny w tym sensie, że działa na większej liczbie procesorów. Bycie niezdefiniowanym (według standardu) nie oznacza, że ​​nie może działać w przypadku niektórych konkretnych architektur. –

4

Standard nie wymaga wskaźnika NULL do oceny wzorca bitowego 0, ale może ocenić na wartość specyficzną dla platformy.

Doing odejmowanie gwarantuje, że po przeliczeniu na wartość całkowitą, NULL 0.

+2

To nie jest powód; można zastosować dowolną rozsądną stałą inną niż "0". Zobacz moją odpowiedź poniżej. –