Конференция "Основная" » Насколько адекватен SizeOf
 
  • Sha © (05.06.08 16:25) [0]
    Моя 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;

  • Palladin © (05.06.08 16:28) [1]
    с месяца два я распинался уже в "прочее" про выравниванивание полей в структурах... поди уже в архиве...


    > Также замечено неадекватное поведение и для структур большего
    > размера.

    оно вполне адекватное... приводи, обосную :)
  • Sha © (05.06.08 16:30) [2]
    > Palladin ©   (05.06.08 16:28) [1]

    я не спрашивал про выравнивание
  • Palladin © (05.06.08 16:31) [3]

    > Sha ©   (05.06.08 16:30) [2]

    а размер записи напрямую зависит от выравнивания
  • Palladin © (05.06.08 16:37) [4]
    а так же от расположения полей

    Type
    TRec1=Record
     a:Int64;
     b:Byte;
     c:Integer;
     d:Byte;
    End;

    TRec2=Record
     a:Int64;
     b:Byte;
     d:Byte;
     c:Integer;
    End;



    абсолютно разные SizeOf, если немного поэкспериментировать, можно выявить как компилятор упаковывает поля записи и как влияет на упаковку директива {$A}
  • Sha © (05.06.08 16:39) [5]
    > Palladin ©   (05.06.08 16:31) [3]

    Про выравнивание все ясно, и что размер записи зависит от выранивания тоже ясно.
    Только неясно, почему t1 имеет размер 1 байт, а t5 - 8.
    Это может примести к ошибкам в операторах типа

    Move(r1,abc,SizeOf(t1)); //тут скопируется 1 байт
    Move(r5,abc,SizeOf(t5)); //тут скопируется 8 байт, а не 5, как ожидаю я

  • Плохиш © (05.06.08 16:41) [6]

    > Sha ©   (05.06.08 16:25)  
    > Моя Delphi7 выводит 1 2 4 8 16 16 16 16 в качестве размеров
    > структур, имеющих размер 1, 2, 4, 8, 9, 10, 12, 16 байт.

    Пиши
    packed record

    и получишь желаемые цифры.
  • Плохиш © (05.06.08 16:43) [7]

    > Про выравнивание все ясно, и что размер записи зависит от
    > выранивания тоже ясно.
    > Только неясно, почему t1 имеет размер 1 байт, а t5 - 8.

    Хм, решил мне телепатор сломать, не выйдет...
  • Palladin © (05.06.08 16:46) [8]
    1. по видимому, компилятор воспринимает запись из одного поля, как просто тип этого поля
    2. move вообще опасно применять к не packed записям, программист всегда должен иметь ввиду, что размер записи может не совпадать, не то чтобы с  суммой размеров полей, но и быть разным даже в зависимости от директив и настроек компилятора.
  • Anatoly Podgoretsky © (05.06.08 16:48) [9]
    > Sha  (05.06.2008 16:25:00)  [0]

    В чем неадекватность, и наверно твое представление не совпадает с представлением компилятора, а понять его не всегда легко.
  • Sha © (05.06.08 16:49) [10]
    > Плохиш ©   (05.06.08 16:43) [7]

    С чего все началось. Было замечено , что тип t44 независио от packed, но в зависимости от расположения звезд на небе имеет размер 44 или 48 байт

     t44 = record
     i1: int64;
     i2: int64;
     i3: int64;
     i4: int64;
     d1: dword;
     d2: dword;
     d3: dword;
     end;

  • Anatoly Podgoretsky © (05.06.08 16:49) [11]
    > Sha  (05.06.2008 16:25:00)  [0]

    Кстати если тебе нужна адекватность, то используй слово Packed
  • Sha © (05.06.08 16:51) [12]
    > Palladin ©   (05.06.08 16:46) [8]
    > move вообще опасно применять к не packed записям

    и как показывает пост [10] и к Packed тоже
  • Sha © (05.06.08 16:52) [13]
    > Anatoly Podgoretsky ©   (05.06.08 16:49) [11]

    Тут не стоит вопрос как обойти проблему и получить адекватность,
    это я знаю.

    Вопрос в том, есть этот глюк в новых версиях Дельфи
  • Palladin © (05.06.08 16:53) [14]

    > Sha ©   (05.06.08 16:49) [10]

    ну, я думаю это что то не реальное. у меня стабильно у packed 44. как воспроизвести?
  • Anatoly Podgoretsky © (05.06.08 16:55) [15]
    > Sha  (05.06.2008 16:30:02)  [2]

    А как ты это представляешь, выравнивание без изменения размера?
  • Sha © (05.06.08 17:05) [16]
    > Palladin ©   (05.06.08 16:53) [14]
    > ну, я думаю это что то не реальное. у меня стабильно у packed 44. как воспроизвести?

    Ты под другими звездами :)

    У нас проект большой.
    Похоже дело в том, что описание типа и
    егo использование в разных модулях.

    Последовательность дейсвий такая.
    Убираем packed, билдим проект, получаем 48
    Ставим packed, компилируем, получаем 48
    Билдим, получаем 44
  • Sha © (05.06.08 17:06) [17]
    > Anatoly Podgoretsky ©   (05.06.08 16:55) [15]
    > А как ты это представляешь, выравнивание без изменения размера?

    Не понял
  • Anatoly Podgoretsky © (05.06.08 17:07) [18]
    > Sha  (05.06.2008 16:52:13)  [13]

    Не знаю, никогда не заморачивался этой проблемой.
    Но Packed всегда работал ожидаемо.
  • Sha © (05.06.08 17:12) [19]
    > Anatoly Podgoretsky ©   (05.06.08 17:07) [18]
    > Мы тоже всегда используем packed. Он работает ожидаемо. Неожиданно работает SizeOf :)

    Еще раз повторюсь, не надо советов, что мне надо сделать.

    Просьба, скомпилировать исходный пример и запустить под другими версиями Дельфи.
 
Конференция "Основная" » Насколько адекватен SizeOf
Есть новые Нет новых   [134491   +8][b:0.001][p:0.002]