sizeof(f_format) возвращает 14 ; Почему это не возвращает 13 ??????
Вам необходимо выключить опцию компилятора 'the Align Record Fields'
(выравнивание полей записи).
Here's the translation into Russian:
Классическая проблема!
В Delphi, когда вы используете тип record, каждый поле выравнивается к конкретной границе в памяти. Это известно как "выравнивание записи". По умолчанию компилятор выравнивает поля различных типов к их естественным границам (например, строки выравниваются к 4- или 8-байтовым границам).
В вашем случае, рекорд f_ format имеет три поля: format_name, file_size и fields. Поле format_name - это строка длиной 8 байт, что означает, что она выравнивается к 8-байтовой границе.
Когда вы используете оператор sizeof для каждого отдельного поля, вы получаете ожидаемые результаты:
sizeof(format_name) возвращает 9, потому что включает в себя null-terminated character array (дополнительный байт для null-терминатора).
sizeof(file_size) возвращает 2, потому что это smallint (16-битное целое число), выравниваемое к 2-байтовой границе.
sizeof(fields) возвращает 2, потому что это также smallint, выравниваемое к 2-байтовой границе.
Однако, когда вы используете оператор sizeof для всей записи (f_ format), вы ожидали, что он вернет 13 (8 байт для строки + 2 байта для поля file_size + 2 байта для поля fields). Но вместо этого он возвращает 14. Почему так?
Почему-то компилятор добавил дополнительный байт padding между полем format_name и полем file_size, чтобы обеспечить правильное выравнивание. Этот padding-байт не является частью какого-либо конкретного поля, но включается в общую длину записи.
Чтобы отключить эту функцию выравнивания записи, вы можете использовать опцию -a- при компиляции вашего кода:
dcc32 -Aa- yourprogram.dpr
Это предотвратит компилятор от добавления padding-байт и уменьшит общую длину записи.
Альтернативно, вы можете использовать ключевое слово packed, чтобы указать, что запись не должна быть выравниваться:
type
f_format = packed record
format_name: string[8];
file_size: smallint;
fields: smallint;
end;
Используя packed, вы говорите компилятору, что поля должны быть плотно упакованы без добавления любых padding-байт. Это может помочь уменьшить использование памяти, но может также повлиять на производительность и совместимость.
Таким образом, дополнительный байт padding добавляется по умолчанию из-за выравнивания записи, которое можно отключить с помощью опции -a- или ключевого слова packed.
В статье рассматривается поведение функции SizeOf в Delphi 2.0 при использовании с рекордом, и автору неожиданно возвращается значение 14 для sizeof(f_format) вместо ожидаемого 13, что объясняется выравниванием полей записи.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS