Эта проблема возникает из-за концепции, известной как выравнивание. Во многих случаях желательно иметь число, размещенное по адресу, который кратен размеру числа в байтах (до некоторого максимума, часто размера указателя платформы). Помещенная таким образом переменная называется выровненной по n-байтовой границе, где n - это число. Точные эффекты этого зависят от процессора. Многие процессоры выполняют математические вычисления быстрее, если данные правильно выровнены. Некоторые даже неспособны выполнять операции (иногда даже операции загрузки) с неподходящими выровненными данными - чтобы работать с такими данными, они должны быть загружены в два регистра, а затем необходимо выполнить серию битовых сдвигов и масок, чтобы получить полезное значение, а затем его нужно вернуть. Думайте об этом, как о хранении половины int
в каждой из двух корзин и необходимости складывать их вместе, чтобы использовать ее, а не просто хранить все int
в одной корзине.
В вашем случае начальный bfType
, вероятно, необходимо выровнять по 2-байтовой границе, а bfSize
, вероятно, необходимо выровнять по 4-байтовой границе. Компилятор должен учесть это, выровняв всю структуру по 4 байта и оставив 2 неиспользуемых байта между bfType
и bfSize
.
Однако при компиляции в одной и той же системе заполнение, вероятно, будет согласованным, возможно, в зависимости от параметров компилятора и конкретного используемого ABI (как правило, вы в безопасности на той же платформе, если не пытаетесь сделать вещи несовместимыми). Вы можете свободно создать другую структуру с теми же первыми 5 членами, и они займут 16 байтов другой структуры в тех же самых позициях.
Если вам действительно нужно избежать такого поведения, вам придется проверить документацию к компилятору. Большинство компиляторов предлагают атрибут или ключевое слово, чтобы объявить переменную как не имеющую выравнивания, и еще один, чтобы указать, что структура не должна иметь отступов. Но это редко бывает необходимо в общем порядке.
person
coppro
schedule
09.12.2009