Почему вычитают нулевого указателя в offsetof ()?

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

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

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

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

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

6
задан Dan Olson 2 April 2010 в 19:39
поделиться

2 ответа

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

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

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

7
ответ дан 9 December 2019 в 22:31
поделиться

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

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

4
ответ дан 9 December 2019 в 22:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: