-
Сорь, не так цитатки поставил
> Anatoly Podgoretsky © (05.06.08 17:07) [18] Мы тоже всегда используем packed. Он работает ожидаемо. Неожиданно работает SizeOf :)
Еще раз повторюсь, не надо советов, что мне надо сделать.
Просьба, скомпилировать исходный пример и запустить под другими версиями Дельфи.
-
> Sha © (05.06.08 16:25)
Можете как то доступно объянить в что вас конкретно не устраивает. Логика выравнивания? Вы хотите сказать что компилятор самопроизвольно меняет размер записи и факт того , что две идентичных записи не смогут корректно взаимодейстовать скомпилированных раздельно если звезда моргнет?
-
Исправления в пост [5]
для > Palladin © (05.06.08 16:31) [3] >Плохиш © (05.06.08 16:43) [7]
Про выравнивание все ясно, и что размер записи зависит от выранивания тоже ясно. Только неясно, почему t1 имеет размер 1 байт, а t9- 16. Это может примести к ошибкам в операторах типа
Move(r1,abc,SizeOf(t1)); //тут скопируется 1 байт Move(r9,abc,SizeOf(t9)); //тут скопируется 16 байт, а не 9, как ожидаю я
-
> Интересны результаты для других версий Delphi.
Для каких других?
-
1 2 4 8 16 16 16 16
Turbo Delphi 2006
-
RAD 2007 1 2 4 8 16 16 16 16
BDS 2006 1 2 4 8 16 16 16 16
-
> oxffff © (05.06.08 17:15) [21] Меня не устраивает, что я должен искать обходные пути для копирования типа t44, даже если он packed
Move(r44,abc,SizeOf(t44)); //тут скопируется 48 байт, а не 44, как ожидаю я
Но не этом вопрос, а про другие весии Дельфи
-
> Игорь Шевченко © (05.06.08 17:18) [24] > Kolan © (05.06.08 17:20) [25]
Понятно, спасибо, будем иметь ввиду
-
> Sha © (05.06.08 17:20) [26] > oxffff © (05.06.08 17:15) [21]
Причем может скопироваться и 44,в зависимости от истории исправлений см [16]
-
> Sha © (05.06.08 17:05) [16]
> Последовательность дейсвий такая. > Убираем packed, билдим проект, получаем 48 > Ставим packed, компилируем, получаем 48 > Билдим, получаем 44
Ну и? Всё описано в документации. 1. SizeOf для типа - константа, которая будет вставлена при компиляции в dcu. 2. Компиляция затрагивает только те модули, исходник которых был изменён, проверяется, кстати, по дате. Соответственно при сборке будут взяты dcu со старым значением SizeOf. 3. Build перекомпилирует все модули, соответственно получаем новые значения размеров. > Sha © (05.06.08 17:17) [22] > Move(r1,abc,SizeOf(t1)); //тут скопируется 1 байт > Move(r9,abc,SizeOf(t9)); //тут скопируется 16 байт, а не > 9, как ожидаю я
Хм, а почему ты ожидаешь не то, что описано в справке?
If two fields share a common type specification, they are packed even if the declaration does not include the packed modifier and the record type is not declared in the state. Thus, for example, given the following declaration
type
TMyRecord = record
A, B: Extended;
C: Extended;
end;
A and B are packed (aligned on byte boundaries) because they share the same type specification. The compiler pads the structure with unused bytes to ensure that C appears on a quadword boundary.
-
> проверяется, кстати, по дате.
этот нюанс, кстати, тоже все время ввиду иметь нужно... решение, мягко говоря, ненадежное и приводит иногда к эффекту, тех самых, космических лучей :)...
-
> Плохиш © (05.06.08 18:01) [29] > 2. Компиляция затрагивает только те модули, исходник которых был изменён Это неверно. Пример. Добавляем в проект модуль
unit SizeOfU2;
interface
type
TMy1= integer;
TMy2= record
pref: int64;
i2: integer;
end;
implementation
end.
и кнопку
uses
SizeOfU2;
procedure TForm1.Button1Click(Sender: TObject);
var
i1: TMy1;
i2: TMy2;
begin
Edit1.Text:=Format('%d %d',
[SizeOf(TMy1), SizeOf(TMy2)]);
end;
компилируем, пускаем, жмем, получаем размеры 4,16 вносим изменения только в добавленный модуль TMy1= int64; компилируем, пускаем, жмем, получаем размеры 8,16 вносим изменения только в добавленный модуль TMy2= packed record компилируем, пускаем, жмем, получаем размеры 8,16 билдим, пускаем, жмем, получаем размеры 8,12 Ситуация усугубляется, если имеется группа проектов. > Хм, а почему ты ожидаешь не то, что описано в справке? А где в справке написано, что размер не packed cтруктуры не равен смещению последнего байта данных+1? Причем только в том случае не равен, когда она содержит более одного поля. > If two fields share a common type specification, А это ты к чему? У меня такого нет. P.S. Ну и еще раз. У меня нет проблем. Я знаю как все это обойти. Мне просто хотелось более адекватного поведения компилятора. Надеялся, что в новых версиях эти грабли отсутствуют. Видно, придется и дальше использовать packed, а чтоб он не ломал выравнивание вводить резервные поля, после каждого изменения packed/не packed перебилдивать, и чтоб уж совсем параноидально застраховаться от ошибочного убирания packed в будущем дополнять запись какой-нить фигней до размера, кратного 16.
-
В проекте используются вложенные структуры данных. Я написал небольшой тест для них:
type
T1n= record
a: byte;
end;
T1p= packed record
a: byte;
end;
T2n= record
a: integer;
b: byte;
end;
T2p= packed record
a: integer;
b: byte;
end;
T11nn= packed record
a: T1n;
b: T1n;
end;
T11np= packed record
a: T1n;
b: T1p;
end;
T11pn= packed record
a: T1p;
b: T1n;
end;
T11pp= packed record
a: T1p;
b: T1p;
end;
T21nn= packed record
a: T2n;
b: T1n;
end;
T21np= packed record
a: T2n;
b: T1p;
end;
T21pn= packed record
a: T2p;
b: T1n;
end;
T21pp= packed record
a: T2p;
b: T1p;
end;
T22nn= packed record
a: T2n;
b: T2n;
end;
T22np= packed record
a: T2n;
b: T2p;
end;
T22pn= packed record
a: T2p;
b: T2n;
end;
T22pp= packed record
a: T2p;
b: T2p;
end;
N11nn= record
a: T1n;
b: T1n;
end;
N11np= record
a: T1n;
b: T1p;
end;
N11pn= record
a: T1p;
b: T1n;
end;
N11pp= record
a: T1p;
b: T1p;
end;
N21nn= record
a: T2n;
b: T1n;
end;
N21np= record
a: T2n;
b: T1p;
end;
N21pn= record
a: T2p;
b: T1n;
end;
N21pp= record
a: T2p;
b: T1p;
end;
N22nn= record
a: T2n;
b: T2n;
end;
N22np= record
a: T2n;
b: T2p;
end;
N22pn= record
a: T2p;
b: T2n;
end;
N22pp= record
a: T2p;
b: T2p;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines.Add(Format('T1n=%d T1p=%d',
[SizeOf(T1n), SizeOf(T1p)]));
Memo1.Lines.Add(Format('T2n=%d T2p=%d',
[SizeOf(T2n), SizeOf(T2p)]));
Memo1.Lines.Add(Format('T11nn=%d T11np=%d T11pn=%d T11pp=%d',
[SizeOf(T11nn), SizeOf(T11np), SizeOf(T11pn), SizeOf(T11pp)]));
Memo1.Lines.Add(Format('T21nn=%d T21np=%d T21pn=%d T21pp=%d',
[SizeOf(T21nn), SizeOf(T21np), SizeOf(T21pn), SizeOf(T21pp)]));
Memo1.Lines.Add(Format('T22nn=%d T22np=%d T22pn=%d T22pp=%d',
[SizeOf(T22nn), SizeOf(T22np), SizeOf(T22pn), SizeOf(T22pp)]));
Memo1.Lines.Add(Format('N11nn=%d N11np=%d N11pn=%d N11pp=%d',
[SizeOf(N11nn), SizeOf(N11np), SizeOf(N11pn), SizeOf(N11pp)]));
Memo1.Lines.Add(Format('N21nn=%d N21np=%d N21pn=%d N21pp=%d',
[SizeOf(N21nn), SizeOf(N21np), SizeOf(N21pn), SizeOf(N21pp)]));
Memo1.Lines.Add(Format('N22nn=%d N22np=%d N22pn=%d N22pp=%d',
[SizeOf(N22nn), SizeOf(N22np), SizeOf(N22pn), SizeOf(N22pp)]));
end;
Получен результат:
T1n=1 T1p=1
T2n=8 T2p=5
T11nn=2 T11np=2 T11pn=2 T11pp=2
T21nn=9 T21np=9 T21pn=6 T21pp=6
T22nn=16 T22np=13 T22pn=13 T22pp=10
N11nn=2 N11np=2 N11pn=2 N11pp=2
N21nn=12 N21np=12 N21pn=6 N21pp=6
N22nn=16 N22np=16 N22pn=16 N22pp=10
Мне не удалось двумя словами описать правила, которыми руководствуется компилятор. Может, кто-нибудь сможет? :)
-
> Sha (05.06.2008 20:04:31) [31]
Ты ждешь от компилятора того, что он уже давно потерял, давно не адекватен, а выравнивание и размер загадка для многих, мало кто в состоянии без проверки сказать точно какой размер будет у структуры.
Раз знаешь как обойти, то плюнь и отойди.
-
> Sha (05.06.2008 21:09:32) [32]
Ой это вообще делает ситуацию неопределенной.
-
> Anatoly Podgoretsky © (05.06.08 21:49) [34]
Да не, нормально, если все делать, как в [31]. Вот только контролировать - проблема, есть шанс не заметить не пакед структуру.
-
> Sha (05.06.2008 22:16:35) [35]
Согласен, но у меня проблем не возникало, может потому что я недопускаю неодназначных конструкций и не использую конструкции типа низкоуровневого Move и подобных. Вот когда коснется, вот тогда и буду разбираться.
-
в d7 разбирался с выравниванием, сложного ниче небыло, работали сложные структуры без packed. позже пришлось вообще отказаться от выравнивания изза переезда на fpc
-
про compile и build - проскакивают старые dcu, d7 и d2006 с этим ведут себя одинакого помоему
-
> Sha © (05.06.08 20:04) [31] > > Плохиш © (05.06.08 18:01) [29]
> > If two fields share a common type specification, > > А это ты к чему? У меня такого нет.
Вообщв-то, в следующих букавках приводиться пример, почему запись T9 имеет размер 16 байт, а неожидаемый, почему-то, тобой 9 байт. Конечно, борланд поступил нехорошо не указав в примере все возможные комбинации записей.
PS. Хотите верить в чудеса, так пожалуйста, никто не запрещает...
|