Ответ 1
Во-первых, это законно применять в C. §6.7.2.1/13:
Внутри объекта структуры небитовые поля и элементы в в которых расположены битовые поля, адреса, которые увеличиваются в порядке которые они объявлены. Указатель на объект структуры, подходящим образом преобразуется, указывает на его начальный член (или если этот член является бит-поле, затем в блок, в котором он находится) и наоборот. В объекте структуры может быть неназванное заполнение, но не на его начало.
Правило псевдонимов гласит следующее (§6.5/7):
Объект должен иметь сохраненное значение, доступ к которому имеет только выражение lvalue, которое имеет один из следующие типы:
- тип, совместимый с эффективным типом объекта,
- квалифицированная версия типа, совместимая с эффективным типом объекта,
- тип, который является подписанным или неподписанным типом, соответствующим эффективному типу Объект,
- тип, который является подписанным или неподписанным типом, соответствующим квалифицированной версии эффективный тип объекта,
- тип агрегата или объединения, который включает один из вышеупомянутых типов среди его члены (в том числе, рекурсивно, член объединенного или объединенного союза) или
- тип символа.
Здесь вы можете получить доступ к нему с помощью указателей типа, совместимого с эффективным типом объекта, и "совокупного или унифицированного типа, который включает один из вышеупомянутых типов среди его членов", поэтому никаких проблем с псевдонимом тоже нет. Таким образом, в C действительно совершенно легально получить доступ к первому члену структуры, указав указатель на структуру на тип рассматриваемого элемента.
В С++, однако, вы часто найдете vtables и другие вещи в начале объекта С++. В вашем конкретном случае, однако, ваша структура имеет стандартный макет, и поэтому это явно разрешено (§9.2/20 в n3290, спасибо Люку Дантону! - С++ 03, по-видимому, имеет аналогичное правило, выраженное в терминах объектов POD).