C 64-разрядное выравнивание указателя

Указатели в 64-разрядной системе - все еще выровненные 4 байта (подобный двойному в системе на 32 бита)? Или они, отмечают выровненных 8 байтов?

Например, в 64-разрядной системе, насколько большой следующая структура данных:

struct a {
    void* ptr;
    char myChar;
}

Был бы указатель на 8 байтов выровненные, вызывающие 7 байтов дополнения для символа (общее количество = 8 + 8 = 16)? Или указатель составил бы выровненные 4 байта (4 байта + 4 байта) порождение 3 байтов дополнения (общее количество = 4 + 4 + 4 = 12)?

Спасибо, Ryan

11
задан DuneBug 24 March 2010 в 07:10
поделиться

5 ответов

Выравнивание и упаковка данных зависят от реализации и обычно могут быть изменены в настройках компилятора (или даже с помощью прагм).

Однако, предполагая, что вы используете настройки по умолчанию, в большинстве (если не во всех) компиляторах общая структура должна составлять 16 байт. Причина в том, что компьютеры читают блок данных с размером своего собственного слова (который составляет 8 байтов в 64-битной системе). Если бы он был дополнен смещением до 4 байтов, следующая структура не была бы должным образом дополнена до 64-битной границы. Например, в случае arr [2] второй элемент массива будет начинаться с 12-байтового смещения, которое не находится на собственной границе байта машины.

6
ответ дан 3 December 2019 в 07:36
поделиться

Стандарт языка не делает никаких заявлений о заполнении. Правила выравнивания зависят от платформы (то есть вы должны выравнивать по-разному, например, на ЦП PowerPC, а не на ЦП x86_64), и они определяются реализацией, что означает, что ваш компилятор может делать все, что работает (и может изменить это поведение с помощью другой команды. -строчные параметры или после обновления версии).

Я твердо верю, что любая рекомендация типа «это обычно то или иное» вводит в заблуждение и, возможно, опасна.

  1. Вы можете написать тестовую программу, которая выполняет пару операторов sizeof () и / или offsetof () и записывает для вас заголовок, содержащий несколько #define с указанием используемых прокладок.

  2. Вы можете использовать autoconf , чтобы сделать это за вас.

  3. По крайней мере, вы должны добавить assert (sizeof (...)) в начало вашей функции main () , чтобы вы получали информацию, когда ваши предположения неправильный.

1
ответ дан 3 December 2019 в 07:36
поделиться

Не думаю, что можно полагаться на какие-то жесткие правила. Я думаю, это зависит от используемого вами компилятора и выбранных вами параметров компиляции.

Лучше всего написать программу, которая проверяет это и выводит файл заголовка, который кодирует правила выравнивания как #define s. Вы также можете просто вычислить то, что вас интересует, прямо в макросах.

6
ответ дан 3 December 2019 в 07:36
поделиться

Обычно в 64-битной системе:

struct a {
    void* ptr;      // size is 8 bytes, alignment is 8
    char myChar;    // size is 1 byte,  alignment is 1
                    // padding of 7 bytes so array elements will be properly aligned
}

Для общего размера 16 байт.

Но все это определяется реализацией - я просто привожу пример, который, вероятно, будет верным для многих (большинства?) 64-битных систем.

3
ответ дан 3 December 2019 в 07:36
поделиться

Вам нужно будет обратиться к документации по конкретному ABI, который вас интересует. Например, вот архитектура System V ABI x86-64 дополнение - вы можете видеть на странице 12, что указатели на этом ABI выровнены по 8 байтов (так что да, структура, которую вы показываете, будет дополнена до 16 байтов).

0
ответ дан 3 December 2019 в 07:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: