Что нового для Delphi XE2 содержит ниже.
Packed Now Принудительное выравнивание байтов записей
Если у вас есть устаревший код, который использует тип упакованной записи, и вы хотите для связи с внешней DLL или с С++, вам нужно удалить слово "упакован" из вашего кода. Упакованное ключевое слово теперь приводит к выравниванию байтов, тогда как в прошлом это не обязательно делало это. Поведение изменение связано с изменениями совместимости выравнивания С++ в Delphi 2009.
Я не понимаю этого. Я борюсь с этим моментом: тогда как в прошлом это не обязательно делало это. То, что я не могу смириться, - это то, что упакованный всегда приводил к выравниванию записей в байтах, насколько мне известно. Может ли кто-нибудь привести пример упакованной записи, которая не выровнена по байтам? Очевидно, что это должно быть в более ранней версии.
Почему документы говорят "если вы хотите установить связь с внешней DLL или с С++, вам нужно удалить слово, упакованное из вашего кода"? Если внешний код использует #pragma pack(1)
, то что нам делать, если он упакован - это пределы?
Как насчет директивы $ALIGN
? Являются ли {$A1} and {$A-}
эквивалентными packed
или есть какой-то дополнительный смысл с packed
?
Кажется, что я что-то упускаю и буду признателен, если кто-нибудь сможет это объяснить. Или документация очень бедна?
Обновление
Я уверен, что документация относится к выравниванию самой записи, а не к макету записи. Здесь небольшая программа, которая показывает, что использование packed
в записи заставляет выравнивание записи быть 1.
program PackedRecords;
{$APPTYPE CONSOLE}
type
TPackedRecord = packed record
I: Int64;
end;
TPackedContainer = record
B: Byte;
R: TPackedRecord;
end;
TRecord = record
I: Int64;
end;
TContainer = record
B: Byte;
R: TRecord;
end;
var
pc: TPackedContainer;
c: TContainer;
begin
Writeln(NativeInt(@pc.R)-NativeInt(@pc.B));//outputs 1
Writeln(NativeInt(@c.R)-NativeInt(@c.B));//outputs 8
Readln;
end.
Это дает тот же результат на Delphi 6, 2010, XE и XE2 32 бит и XE 64 бит.