Ответ 1
Почему это ((type *) 0) → member, not (type *) → member
Просто потому, что (type*)->member
будет недопустимым синтаксисом, поэтому typeof
будет невозможно. Поэтому он использует указатель NULL
, который он не разыскивает в любом случае - он используется так, чтобы typeof
мог ссылаться на член.
Как это работает:
-
Тройка
typeof
используется для объявления указателя типа элемента. Этот указатель получает инициализируется указателем, переданным вызывающим абонентом -
Смещение этого члена в структуре вычитается из адреса указателя: это дает адрес содержащего объекта
Проблема с Subtler: почему бы не избавиться от typeof
и просто сделать ptr - offsetof
. Мы все равно отбрасываем его на char *
, верно? В этом случае вы можете передать что-либо как ptr
, и компилятор ничего не скажет. Итак, все вещи typeof
существуют для (рудиментарного) контроля типов.