У меня есть побитовая структура C ++:
struct MXBodyStateCompact {
uint8_t angle : 8;
uint16_t positionX : 16;
uint16_t positionY : 16;
void Set(MXBodyState state);
void GetState(MXBodyState *state);
};
Он отлично работает на iPhone — 5 байт на экземпляр. Именно то, что мне нужно.
Но попробуйте на iOS Simulator и Android. На каждый экземпляр выделяется 6 байтов. В то время как angle
по-прежнему 1 байт (в соответствии с sizeof
), занимает 2 байта в памяти:
(gdb) p sizeof(*this)
$4 = 6
(gdb) p sizeof(this->angle)
$5 = 1
(gdb) p sizeof(this->positionX)
$6 = 2
(gdb) p sizeof(this->positionY)
$7 = 2
(gdb) p this
$8 = (struct MXBodyStateCompact *) 0x7ee5d035
(gdb) p &this->angle
$9 = (uint8_t *) 0x7ee5d035 "X"(gdb) p &this->positionX
$10 = (uint16_t *) 0x7ee5d037
(gdb) p &this->positionY
$11 = (uint16_t *) 0x7ee5d039
Как видите, между адресами 2 байта angle
и адрес positionX
,
Есть ли способ заставить компилятор / систему соблюдать размер структурных полей? Или нужно найти какой-то другой способ, как бороться с моим двоичным файлом? (Я использую эту структуру для обработки данных из двоичных файлов.)
использование __attribute__((packed))
сказать gcc или clang не вставлять отступ между членами этой структуры.
struct __attribute__((packed)) MXBodyStateCompact {
uint8_t angle : 8;
uint16_t positionX : 16;
uint16_t positionY : 16;
void Set(MXBodyState state);
void GetState(MXBodyState *state);
}
Так же : 8
а также : 16
кажется ненужным.
Проверь это : http://en.wikipedia.org/wiki/Data_structure_alignment
Выравнивание данных означает размещение данных со смещением памяти, равным некоторому кратному размеру слова, что повышает производительность системы благодаря тому, как процессор обрабатывает память. Чтобы выровнять данные, может быть необходимо вставить несколько бессмысленных байтов между концом последней структуры данных и началом следующей, которая является заполнением структуры данных.