Дмитрий Орловский дата публикации 15-10-2008 03:47 КАТЕГОРИЯ | | КОМПИЛЯТОР.Неправильное распределение полей в объекте | ПРОДУКТ | | Delphi 7 | ПЛАТФОРМА | | Windows |
Класс 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 байта по-умолчанию должно выравниваться на границу слова. Простим компилятору, это его личное дело, как выравнивать поля. Программист не ошибется, если будет обращаться к полям по имени, а не пытаться вычислить смещение вручную.
Каждому — свое.
[Инкапсуляция] [Записи (record)]
Обсуждение материала [ 16-05-2009 13:14 ] 8 сообщений |