Неправильное распределение полей в объектеИсточник: delphikingdom Дмитрий Орловский
Автор: Дмитрий Орловский, Королевство Delphi
Класс TColumn описан в модуле DBGrid. Речь идет о поле FAssignedValues типа TColumnValues. Этот тип объявлен как set of TColumnValue и его размер равен 2 байтам. Согласно принятым правилам поле рассматриваемого типа должно выравниваться по четным адресам и иметь смещение +60. Тем не менее, оно имеет смещение +59, непосредственно примыкая к предыдущему однобайтовому полю. Результатом является значение TColumn.Instancesize=64, хотя при использовании декларируемого правилами выравнивания эта величина должна быть равна 68. Тестовый код: uses DBGrids; type PColumnValues = ^TColumnValues; var obj: TColumn; begin obj:=TColumn.Create(nil); Memo1.Lines.Clear; //проверка смещения поля FAssignedValues: (PWord(Integer(obj)+59))^:=247; //устанавливаем FAssignedValues Memo1.Lines.Add(IntToStr(Word(obj.AssignedValues))); //читаем FAssignedValues //для того чтобы метод чтения свойства Readonly возвращал в качестве //значения FReadonly, нужно включить cvReadOnly в AssignedValues: (PColumnValues(Integer(obj)+59))^:=[cvReadOnly]; //проверка смещения поля FReadonly: (PByte(Integer(obj)+58))^:=1; //устанавливаем FReadonly Memo1.Lines.Add(IntToStr(Byte(obj.ReadOnly))); //читаем FReadonly obj.Free; end; Типовые решения При необходимости следует учитывать правильные смещения полей: FField +12 FFieldName +16 FColor +20 FWidth +24 FTitle +28 FFont +32 FImeMode +36 FImeName +40 FPickList +44 FPopupMenu +48 FDropDownRows +52 FButtonStyle +56 FAlignment +57 FReadonly +58 FAssignedValues +59 FVisible +61 FExpanded +62 FStored +63 Комментарий Компилятор нарушает утверждение, сделанное в справке по выравниванию полей в записях и классах: Type Alignment Set types size of the type if 1, 2, or 4, otherwise 1Т.е., множество размером 2 байта по-умолчанию должно выравниваться на границу слова. Простим компилятору, это его личное дело, как выравнивать поля. Программист не ошибется, если будет обращаться к полям по имени, а не пытаться вычислить смещение вручную. Каждому - свое. |