Указатели в 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
Выравнивание и упаковка данных зависят от реализации и обычно могут быть изменены в настройках компилятора (или даже с помощью прагм).
Однако, предполагая, что вы используете настройки по умолчанию, в большинстве (если не во всех) компиляторах общая структура должна составлять 16 байт. Причина в том, что компьютеры читают блок данных с размером своего собственного слова (который составляет 8 байтов в 64-битной системе). Если бы он был дополнен смещением до 4 байтов, следующая структура не была бы должным образом дополнена до 64-битной границы. Например, в случае arr [2] второй элемент массива будет начинаться с 12-байтового смещения, которое не находится на собственной границе байта машины.
Стандарт языка не делает никаких заявлений о заполнении. Правила выравнивания зависят от платформы (то есть вы должны выравнивать по-разному, например, на ЦП PowerPC, а не на ЦП x86_64), и они определяются реализацией, что означает, что ваш компилятор может делать все, что работает (и может изменить это поведение с помощью другой команды. -строчные параметры или после обновления версии).
Я твердо верю, что любая рекомендация типа «это обычно то или иное» вводит в заблуждение и, возможно, опасна.
Вы можете написать тестовую программу, которая выполняет пару операторов sizeof ()
и / или offsetof ()
и записывает для вас заголовок, содержащий несколько #define
с указанием используемых прокладок.
Вы можете использовать autoconf
, чтобы сделать это за вас.
По крайней мере, вы должны добавить assert (sizeof (...))
в начало вашей функции main ()
, чтобы вы получали информацию, когда ваши предположения неправильный.
Не думаю, что можно полагаться на какие-то жесткие правила. Я думаю, это зависит от используемого вами компилятора и выбранных вами параметров компиляции.
Лучше всего написать программу, которая проверяет это и выводит файл заголовка, который кодирует правила выравнивания как #define
s. Вы также можете просто вычислить то, что вас интересует, прямо в макросах.
Обычно в 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-битных систем.
Вам нужно будет обратиться к документации по конкретному ABI, который вас интересует. Например, вот архитектура System V ABI x86-64 дополнение - вы можете видеть на странице 12, что указатели на этом ABI выровнены по 8 байтов (так что да, структура, которую вы показываете, будет дополнена до 16 байтов).