Ненулевая константа существует потому, что макрос не работает с нулевыми указателями. Мы знаем, что значение нулевого указателя является константой нулевого указателя, которая оценивается как 0
:
C ++ Стандарт 4.10 / 1 Преобразование указателя [conv.ptr]:
Константа нулевого указателя является интегралом
константное выражение (5.19)
целочисленный тип, который оценивается в ноль.
константа нулевого указателя может быть преобразована
на указатель типа; результатом является
значение нулевого указателя этого типа и является
отличается от любого другого значения
указатель на объект или указатель на
тип функции ....
Это релевантное предложение в отношении преобразования из производного класса в тип указателя базового класса:
C ++ Стандарт 4.10 / 3 Преобразования указателей [conv.ptr]:
Значение типа «указатель на cv D»
где D - тип класса, может быть
преобразован в значение типа
«Указатель на cv B», где B является базой
класс (пункт 10) D. Если B является
недоступный (пункт 11) или неоднозначный
(10.2) базовый класс D, программа, которая
требует этого преобразования
плохо сформирован. Результат
преобразование является указателем на базу
подобъект класса производного класса
объект. Значение нулевого указателя:
преобразуется в значение нулевого указателя
тип пункта назначения.
В основном нулевые указатели предотвращают срабатывание арифметики указателей во время преобразования из производной в базовую; вы просто получите еще один нулевой указатель. Арифметика используется для «исправления» ненулевых указателей во время таких преобразований, чтобы указывать на соответствующий подобъект. Макрос offsetofclass
зависит от этой арифметики для определения смещения.
Используемое число 8
является произвольным. Вы могли использовать любое число, например, 1
или 4
, если оно не равно нулю.