Дмитрий Орловский
Автор: Дмитрий Орловский, Королевство Delphi
КАТЕГОРИЯ |
|
КОМПИЛЯТОР.Неправильное распределение полей в объекте |
ПРОДУКТ |
|
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 байта по-умолчанию должно выравниваться на границу слова. Простим компилятору, это его личное дело, как выравнивать поля. Программист не ошибется, если будет обращаться к полям по имени, а не пытаться вычислить смещение вручную.
Каждому - свое.
Ссылки по теме