Я собираюсь предположить, что когда у вас есть struct_second_t
, вы на самом деле имели в виду second_struct_t
, иначе ваш код не скомпилируется.
Проблема в том, что f
в some_struct
является указателем на first_struct_t
, а не на second_struct_t
.
Я должен добавить, что приведение в struct_second_t *s = (struct_second_t *) p->f;
скрывает предупреждающее сообщение. В общем, если вам нужно привести один указатель к другому, вы чаще всего будете вызывать неопределенное поведение. Это не всегда верно, но является довольно хорошим ориентиром.
В ответ на комментарий.
Сначала кажется, что вы не получите это предупреждение с gcc для x86 (32 и 64 бит), поскольку нет требований к выравниванию для регистров общего назначения, хотя выравнивание может повысить производительность (см. это SO post для получения дополнительной информации). Что касается того, почему clang выдает это предупреждение, возможно, из-за производительности или у них нет исключения, как у gcc для x86.
Во-вторых, то, что вы пытаетесь выполнить, похоже на то, что макрос container_of
делает в ядре Linux. container_of
обычно определяется как:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
При поиске единственное, что я нашел, что решает вашу проблему, это эта фиксация, чтобы изменили свою версию container_of
, включив приведение к void*
.
По сути, я считаю, что проблема в том, что вы знаете, что p->f
на самом деле указывает на second_struct_t
, которого нет у вашего компилятора, и поэтому выдает предупреждение. Так что вы можете либо не делать этого, либо использовать void*
.
Дополнительный:
Кажется, что Mozilla решает проблему, также приводя к void*
:
Наконец, я бы рекомендовал взглянуть на container_of
и использовать его вместо того, чтобы полагаться на тот факт, что первый элемент структуры является другой структурой. Таким образом, ваш код будет более устойчивым, если кто-то еще изменит порядок элементов структуры, он все равно будет работать. Вам нужно будет добавить приведение void*
к container_of
, чтобы избежать предупреждения. Обратите внимание, что в архитектурах с проблемами выравнивания у вас не должно быть проблем во время выполнения, если вы всегда правильно меняете тип между дочерним и родительским.
person
missimer
schedule
19.10.2015
some_struct *p
иstruct_second_t *s
не взаимозаменяемы (указатель на структуру всегда указывает на ее первый элемент, а это не так). Вы имеете в видуfirst_struct_t *s = (first_struct_t *) p->f;
? - person David Ranieri   schedule 19.10.2015p->f
неfirst_struct_t
? Неfirst_struct_t *
? - person Andrew Henle   schedule 19.10.2015first_struct_t
a Выравнивание по 8 байт. - person user3528438   schedule 19.10.2015