ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
19 мая
1020508 Топик полностью
fk0, легенда (23.07.2020 21:52, просмотров: 832) ответил Гyдвин на ВОТ!!!
Aioeeeaaoiioaaie ieeooaaiieeo iaaiie! 

Писал здесь уже несколько раз -- как об стену горох. Всё компилятор виноват -- заставь дурака богу молиться: лоб расшибёт...


https://coliru.stacked-crooked.com/a/b6aa333662a427bf


IH.conag: addr=0x601b03, sizeof = 4, alignas = 4, type: unsigned int const
&buffer[32]: addr=0x7ffe1cff3b38, sizeof = 8, alignas = 8, type: unsigned char* const
IX.conag: addr=0x601ad4, sizeof = 4, alignas = 4, type: unsigned int const
IY.conag: addr=0x601af3, sizeof = 4, alignas = 1, type: Unaligned_U32 const

Адрес у IH.conag, видишь, нечётный? Потму, что my_id и type_sens занимают три байта. Вроде должно быть понятно. Если бы ты не делал упакованную структуру, то оно само бы навставляли "лишних" байт и всё выравнило как надо. А так получается полная хуйня. Упакованная структура есть, но с ней никто никак не знает как работать: потому, что внутри неё лежат ОБЫЧНЫЕ, а не "упакованные" типы (alignas = 4) по "упакованным" (нечётным) адресам.


И у каждого типа есть такие атрибуты как sizeof и alignof, указывающие на размер элемента (с учётом выравнивания следующего в массиве) и необходимое выравнивание для данного элемента. А типы, как я сказал, ОБЫЧНЫЕ, поэтому malloc() нихера не знает, что там волшебный тип, а видит, что тип там U32, который в нормальных условиях вполне себе выравненный, и вызывает оптимизированную функцию которая быстро копирует 32-битными словами, а не по одному байтику (что нужно для невыравненных данных).


Проблема в том, что alignas -- атрибут типа. А типы у тебя в структуре -- обычные. Можно изголиться и ввести новые типы (структуры) с другим значением alignas (см. определение IY) -- но это бред и наркомания. Я 100500 раз писал: все эти выебоны с самодельными типами, упакованными структурами и прочее нужны тому, кто нихера программировать не умеет в той мере, чтоб написать на обычном стандартном C сериализацию ручками. И такой код ничем не будет хуже сгенерированного компилятором.


Каждый раз, когда ты используешь упакованные структуры, или нестандартное выравнивание, ты нарываешься на то, что с такими структурами нихера невозможно нормально работать. Да, обращения к членам структуры комполятор сгенерирует как надо. Но в выражении memcpy(&IH.config...) -- это уже нихера не обращение к члену, которое компилятор знает как, а получение указателя на элемент структуры. И какого он, спрашивается должен быть типа? Правильно, записанного в структуре U32, с alignas(4)... По указателю с членами работать нихера не возможно -- и это одна из причин, почему упакованных структур нихера нет в стандарте. И там много подводных камней ещё всплывёт на ровном месте.

[ZX]