![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Насколько адекватен SizeOf
Sha © (2008-06-05 16:25:00)Моя Delphi7 выводит 1 2 4 8 16 16 16 16 в качестве размеров структур, имеющих размер 1, 2, 4, 8, 9, 10, 12, 16 байт.
Также замечено неадекватное поведение и для структур большего размера.
Интересны результаты для других версий Delphi.
Тестилось на этом коде
type
t1 = record
b: byte;
end;
t2 = record
w: word;
end;
t4 = record
d: dword;
end;
t8 = record
i: int64;
end;
t9 = record
i: int64;
b: byte;
end;
t10 = record
i: int64;
w: word;
end;
t12 = record
i: int64;
d: dword;
end;
t16 = record
i: int64;
i2: int64;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Edit1.Text:=Format('%d %d %d %d %d %d %d %d',
[SizeOf(t1), SizeOf(t2), SizeOf(t4), SizeOf(t8),
SizeOf(t9), SizeOf(t10), SizeOf(t12), SizeOf(t16)]);
end;
KSergey (2008-06-07 11:45:00) [1]> KSergey © (07.06.08 09:42) [77]
> Формально по ссылке наверное написано правильно,
Беда только в том, что не про дельфи :)
Но это обсуждение натолкнуло меня на мысль, что в дельфи у автора оно как-то примерно так же устроено, похоже.
KSergey (2008-06-07 09:42:00) [2]Может и не в тему
http://forum.sources.ru/index.php?showtopic=110906
Формально по ссылке наверное написано правильно, но, если честно, моему осознанию сильно мешает то, что автор не привел свое толкование примененных теринов.
На сколько я смог понять, между словами "выравнивание" и "размер" у него подразумевается знак равенства.
Anatoly Podgoretsky (2008-06-07 01:18:00) [3]Я уже писал, для оптимизации компилятора и частично работы.
Так писать проще, достаточно провести анализ только для первой переменной, остальные автоматическу получаются выровнеными.
tesseract (2008-06-06 19:37:00) [4]
> зачем потребовался такой не совсем очевидный алгоритм определения
> размера записи.
Может связано с оптимизацией работы кучи ?
Sha (2008-06-06 18:32:00) [5]> Anatoly Podgoretsky © (06.06.08 16:45) [70]
> ... а есть ли при работе ошибка?
В [51] я попытался кратко изложить логику работы компилятора при выравнивании полей записи и определении размера записи.
Более того, Борланд следует приведенному алгоритму и во вложенных структурах.
Ошибок не обнаружено :)
Там же я сделал предположение, зачем потребовался такой не совсем очевидный алгоритм определения размера записи.
Здесь у Борланда все сходится идеально.
Palladin (2008-06-06 17:58:00) [6]так, еще раз и без косяков... :)
{$A8}
TMR1=Record
a:Byte;
"просвет" 1b
c:Word;
d:Byte;
"просвет" 1b
e:Word;
End; 8b
TMR2=Record
a:Byte;
"просвет" 1b
c:Word;
d:Byte;
"просвет" 3b
e:Integer;
End; 12b
{$A2}
TMR1=Record
a:Byte;
"просвет" 1b
c:Word;
d:Byte;
"просвет" 1b
e:Word;
End; 8b
TMR2=Record
a:Byte;
"просвет" 1b
c:Word;
d:Byte;
"просвет" 1b
e:Integer;
End; 10b
Palladin (2008-06-06 17:07:00) [7]в последнем типе ошибся
{$A2}
TMR2=Record
a:Byte;
// 1b
c:Word;
d:Byte;
// 1b
e:Integer;
End; // 10b
Palladin (2008-06-06 16:57:00) [8]
> Лишние байты не принадлежат последнему полю.
конечно не приналежат они "боксам" внутри записи принадлежат, а вот размеры "боксов" уже плавают в зависимости от самого большого типа и от директивы выравнивания
интересный эксперимент
{$A8}
TMR1=Record
a:Byte;
// - щель 1b
c:Word;
d:Byte;
// - щель 1b
e:Word;
End; // 8b
TMR2=Record
a:Byte;
// 1b
c:Word;
// 2b
d:Byte;
// 3b
e:Integer;
End; // 12b
хотя
{$A2}
TMR1=Record
a:Byte;
// - щель 1b
c:Word;
d:Byte;
// - щель 1b
e:Word;
End; // 8b
TMR2=Record
a:Byte;
// 1b
c:Word;
// 2b
d:Byte;
// 1b
e:Integer;
End; // 10b
Anatoly Podgoretsky (2008-06-06 16:45:00) [9]Это понятно, но это психология, тут претензии только к Борланду, а есть ли при работе ошибка?
Sha (2008-06-06 16:40:00) [10]> Плохиш © (06.06.08 15:15) [62]
Вот пример, который прояснит мою позицию.
Известно, что память в Д7 под строки выделяется двойными словами. И если длина строки кратна 4, то терминатор попадает в отдельный dword. Но никому ведь не приходит в голову говорить, что терминатор занимает или под него выделено двойное слово, потому что три лишних байта потребовались строке в целом, а не терминатору. Т.е. размер строки был округлен до 4 вверх.
Так и случае с записями. Лишние байты не принадлежат последнему полю. На мой взгляд.
Плохиш (2008-06-06 15:46:00) [11]Нифигасе, страсти накалились 8-O
(2008-06-06 15:40:00) [12]Удалено модератором
Примечание: offtopic
Anatoly Podgoretsky (2008-06-06 15:34:00) [13]Удалено модератором
Примечание: offtopic
Sha (2008-06-06 15:30:00) [14]Удалено модератором
Примечание: offtopic
(2008-06-06 15:23:00) [15]Удалено модератором
Примечание: offtopic
Плохиш (2008-06-06 15:16:00) [16]
> Anatoly Podgoretsky © (06.06.08 15:09) [61]
+1 :-(
Плохиш (2008-06-06 15:15:00) [17]
> Sha © (06.06.08 14:03) [57]
> > Плохиш © (06.06.08 13:42) [55]
> > для последнего поля выделяется один байт, только в одном
> случае, когда выравнивание установлено в 1 {A1}.
>
> Здесь, конечно, дело вкуса.
>
> Тебе почему-то удобней думать, что последнее поле, в котором
> лежит однобайтовая переменная, занимает 8 байт,
Согласись, что понятия "занимает байт" и "распределено байт" несколько отличаются. И мне как-то удобней думать, что структуры данных занимают столько байт, как это описано в документации разработчиков компилятора.
Anatoly Podgoretsky (2008-06-06 15:09:00) [18]> Sha (06.06.2008 14:52:00) [60]
Я уже матюгался? Нет, ну тогда матюгаюсь, Борланд пошел по попсовому пути, набросать много не нужных функций, и попутно теряя надежность компилятора, делая всякие колокольчики. А переход к ebarcader может ситуацию еще больше ухудшить. Все лучшие кадры подарили или Микрософту или Ораклу и другим фирмам.
Sha (2008-06-06 14:52:00) [19]> Anatoly Podgoretsky © (06.06.08 14:41) [59]
Это не я писал, хотя это верно :)
Последовательность действий по воспроизведению бага описана [16].
Тут суть в том, что модули на диске не перезаписываются и дата у них не меняется.
Изменения делаются непосредственно в среде Дельфи.
И некоторые из них Дельфи учитывает в зависимых модулях, а некоторые - нет.
Anatoly Podgoretsky (2008-06-06 14:41:00) [20]> Sha (06.06.2008 14:05:58) [58]
Добавление Packed это по сути и есть изменение типа поля.
Но я уже писал, что перекомпиляция связаных модулей не зависит от содержимого, а только от дат, основано на make.
А по твоим словам ты же именно модуль меняешь