Согласно стандартам C и C ++, неопределенное поведение для доступа к переменной данного типа через указатель на другой тип.Пример:
int a;
float * p = (float*)&a; // #1
float b = *p; // #2
Здесь # 2 вызывает неопределенное поведение.Назначение на # 1 называется "типом наказания".Термин «псевдоним» относится к идее, что несколько различных переменных-указателей могут указывать на одни и те же данные - в этом случае p
псевдоним данных a
.Правовой псевдоним является проблемой для оптимизации (которая является одной из основных причин превосходной производительности Fortran в определенных ситуациях), но здесь мы имеем дело с незаконным псевдонимами.
Ваша ситуацияничем не отличается;Вы получаете доступ к данным на buffer
через указатель на другой тип (т. е. указатель, который не char *
).Это просто недопустимо.
В результате: у вас никогда не должно было быть данных на buffer
.
Но как их решить?Убедитесь, что у вас есть действительный указатель!Есть одно исключение для типа punning, а именно доступ к данным через указатель на тип char, который является разрешенным.Таким образом, мы можем написать это:
record_t data;
record_t * p = &data; // good pointer
char * buffer = (char*)&data; // this is allowed!
return p->len; // access through correct pointer!
Принципиальное отличие состоит в том, что мы храним реальные данные в переменной правильного типа, и только после выделения этой переменной мы будем рассматривать переменную как массив символов(что разрешено).Мораль здесь в том, что массив символов всегда идет вторым, а реальный тип данных - первым.