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