Чтобы добавить к ответу Дина, вот кое-что о преобразованиях указателя в целом. Я забыл, что термин для этого, но указатель на приведение указателя не выполняет преобразование (так же, как int в float). Это просто переосмысление битов, на которые они указывают (все для выгоды компилятора). «Неразрушающее обращение» Я думаю, что это было. Данные не меняются, только то, как компилятор интерпретирует то, на что указывают.
например.,
Если ptr
является указателем на object
, компилятор знает, что существует поле с определенным смещением с именем type
типа enum type
. С другой стороны, если ptr
приведен к указателю другого типа, cons_object
, он снова узнает, как аналогичным образом получить доступ к полям cons_object
, каждое из которых имеет свои собственные смещения.
Для иллюстрации представьте макет памяти для cons_object
:
+---+---+---+---+
cons_object *ptr -> | t | y | p | e | enum type
+---+---+---+---+
| c | a | r | | object *
+---+---+---+---+
| c | d | r | | object *
+---+---+---+---+
Поле type
имеет смещение 0, car
равно 4, cdr
равно 8. Чтобы получить доступ к полю автомобиля, все, что нужно сделать компилятору, это добавить 4
к указателю на структуру.
Если указатель был приведен к указателю на object
:
+---+---+---+---+
((object *)ptr) -> | t | y | p | e | enum type
+---+---+---+---+
| c | a | r | |
+---+---+---+---+
| c | d | r | |
+---+---+---+---+
Все, что нужно знать компилятору, - это поле с именем type
со смещением 0. Все, что находится в памяти, находится в памяти.
Указатели даже не должны быть связаны между собой. Вы можете иметь указатель на int
и приводить его к указателю на cons_object
. Если вам нужно было получить доступ к полю car
, это похоже на обычный доступ к памяти. Это имеет определенное смещение от начала структуры. В этом случае, что находится в этом месте памяти, неизвестно, но это неважно. Для доступа к полю требуется только смещение, и эта информация находится в определении типа.
Указатель на int
указывает на блок памяти:
+---+---+---+---+
int *ptr -> | i | n | t | | int
+---+---+---+---+
Приведение к указателю cons_object
:
+---+---+---+---+
((cons_object *)ptr) -> | i | n | t | | enum type
+---+---+---+---+
| X | X | X | X | object *
+---+---+---+---+
| X | X | X | X | object *
+---+---+---+---+