Не могу найти однозначного ответа на следующий вопрос.
Допустим, у меня имеется какая-то структура данных:
struct Data
{
int id;
double values[1024]
// ...
uint8_t flags;
// ...
};
И она лежит в буфере в не выровненном состоянии. Мне известно смещение, по которому объект данной структуры лежит в буфере. Я бы хотел считать определенное поле из этого объекта. Например, поле flags
.
uint8_t getFlags(uint8_t *_buffer, size_t _offset)
{
uint8_t *pu = _buffer + _offset;
// ...
}
1) Проблема в том, что Стандарт C
говорит, что неопределенным поведением является даже попытка сохранить в указателе адрес с не правильным выравниванием:
Data *pd = (Data*)pu;// UB
2) Естественно, попытка разыменовать указатель, в котором хранится адрес с неподходящим для целевого типа выравниванием - это неопределенное поведение.
const uint8_t f = pd->flags;// UB
3) Я бы мог попытаться вытащить данные без разыменования:
uint8_t f;
memcpy(&f, pu + offsetof(Data, flags), sizeof(uint8_t));
Но этот способ выглядит подозрительно. Даже в рамках языка C
.
В общем, я хочу понять, как правильно выковыривать определенные поля из объектов, которые лежат в буферах в не выровненном состоянии. Это частая задача, особенно при работе с сетью, драйверами и встраиваемыми системами.
Единственный переносимый способ интерпретировать определённый тип данных из потока (буфера) байт, не опасаясь проблем доступа к невыровненным данным - это побайтово (например, с помощью memcpy
) скопировать эти данные в место, где нужное выравнивание обеспечивается.
В случае доступа к невыровненным данным в зависимости от используемой архитектуры можно получить либо проседание производительности, либо, так называемую, ошибку шины (Bus error). В общем случае всё это приводит к неопределённому поведению.
Тем не менее при использовании упаковки структур (если компилятор такое поддерживает), ошибок с доступом к невыровненным данным не будет, но сам факт наличия упаковки может привести к проседанию производительности, хотя это безусловно лучше, чем UB.
В сухом остатке: если есть возможность - делайте упаковку, если нет - копируйте побайтово. Степень оверхеда от всего этого надо смотреть на конкретных примерах конкретных же архитектур.
На основании статьи How to Access Safely Unaligned Data.
Ошибка: QMetaProperty::read: Unable to handle unregistered datatype 'QObjectList' for property 'ViewshedGeoElement_QMLTYPE_43::PointLogLag'
Предположим, существует некоторый класс foo с конструктором по умолчаниюВ main() происходит его создание
Пытаюсь установить MSVS 2017На этапе установки SDK установщик начинает требовать какие-то пакеты