Зачем вычитать нулевой указатель в offsetof ()? - PullRequest
6 голосов
/ 02 апреля 2010

Linux stddef.h определяет offsetof() как:

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

, тогда как статья в Википедии о offsetof() (http://en.wikipedia.org/wiki/Offsetof) определяет его как:

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

Зачем вычитать (char *)0 в версии Википедии? Есть ли какой-нибудь случай, когда это действительно будет иметь значение?

Ответы [ 2 ]

7 голосов
/ 03 апреля 2010

Первая версия преобразует указатель в целое число с приведением, которое не является переносимым.

Вторая версия более переносима среди более широкого спектра компиляторов, поскольку она использует арифметику указателей компилятором для получения целочисленного результата вместо преобразования типа.

Кстати, я был редактором, который добавил исходный код к записи Wiki, которая была формой Linux. Более поздние редакторы изменили его на более портативную версию.

4 голосов
/ 02 апреля 2010

Стандарт не требует, чтобы указатель NULL оценивался для битовой комбинации 0, но может оцениваться для конкретного значения платформы.

Выполнение вычитания гарантирует, что при преобразовании в целочисленное значение NULL равно 0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...