Будет ли когда-либо упаковывать структуру смещать смежную память? - PullRequest
0 голосов
/ 26 февраля 2019

Рассмотрим следующую структуру

struct a{
    uint16_t foo1
    uint16_t foo2
    uint32_t foo3
    uint64_t foo4
    uint16_t foo5
    uint16_t foo6
}__attribute__(packed);

Это 20 байтов в длину.Это нормально, так как все в структуре выровнено по границам слов.

Однако, что произойдет, если разработчик из лучших побуждений сделает следующее:

static struct a foo;
static uint64_t b;

Теоретически это приведет к смещению bчерез границу слова.

Интересно, что gcc, кажется, выравнивает foo до 16 байтов, однако (если мои знания о сборке верны), это позволяет b быть смещенным:

.local  foo.2476
.comm   foo.2476,20,16
.local  b.2477
.comm   b.2477,8,8

Я что-то здесь упускаю, или это пример опасности упаковки структуры?

1 Ответ

0 голосов
/ 26 февраля 2019

Однако, что произойдет, если разработчик из лучших побуждений сделает следующее:

static struct a foo;
static uint64_t b;

Теоретически это приведет к смещению b через границу слова.

Нет, нет особой причины для неправильного выравнивания b в этом случае, не больше, чем если бы вместо этого у вас было

static char foo;
static uint64_t b;

.Предположим, что uint64_t имеет требование выравнивания больше 1, некачественный компилятор может сместить b в этом случае, но на практике вы вряд ли когда-либо увидите такой результат.Компиляторы размещают хранилище для переменных по своему усмотрению, и обычно по хорошо выровненным адресам.

Интересно, что gcc, похоже, выравнивает foo с 16 байтами, однако (если мои знания о сборке верны), онпозволяет b быть смещенным: [...]

Я что-то здесь упускаю, или это пример опасностей упаковки структуры?

Вы почти наверняка что-то упустили,Я бы поставил доллары на пончики, что uint64_t вашей машины требует 4-байтового, а не 8-байтового требования выравнивания.

...