Форум: "Начинающим";
Текущий архив: 2006.02.19;
Скачать: [xml.tar.bz2];
ВнизКак выровнять record на 149 Найти похожие ветки
← →
Приятель (2006-02-03 06:27) [0]Есть рекорд :
TArea4 = record
...
Temp1 : array [0..14] of Byte;
end;
И её SizeOf(TArea4) выдаёт 149.
Мне понадобилось в неё добавить ещё один параметр и я это сделал так :TArea4 = record
...
Tag : Integer;
Temp1 : array [0..14 -4] of Byte;
end;
Но почему то её SizeOf(TArea4) после этого стала не 149, а 152. Тогда я сделал :Temp1 : array [0..14 -4 -3] of Byte;
Но после этого её SizeOf(TArea4) стала 148, я долго мучался с этой проблемой, пытаясь добиться размера в 149, но так ничего и не получилось. Мастера, помогите, пожалуйста ?
← →
MBo © (2006-02-03 06:54) [1]packed record
← →
Приятель (2006-02-03 07:00) [2]А что это значит? Учтите, что поля в рекорде не должны смещаться. Потому, что тогда сместятся все данные и при загрузке или assign, всё спутается.
← →
MBo © (2006-02-03 07:13) [3]>А что это значит?
Такой вопрос стоит задать хелпу.
>Учтите, что поля в рекорде не должны смещаться
Ну что тут сказать... Изначально нужно было правильно проектировать, с Packed или с предопределенным выравниванием полей (директива {$An})
← →
MBo © (2006-02-03 07:19) [4]P.S. Если не удастся разрешить проблему, один из способов обойти её такой (если я правильно понял задачу) - оставить старое объявление, и
PInteger(@Rec.Temp1)^:=Tag;
и
Tag:=PInteger(@Rec.Temp1)^;
← →
Приятель (2006-02-03 07:37) [5]На будущее учту.
А предопределённое выравнивание полей никак нельзя привести к 149? И почему же раньше то оно приводилось?
← →
TUser © (2006-02-03 09:38) [6]В Паскале поля записей размещаются по адресу, кратному 4 (на 32-битных машинах). Считается, что это ускоряет процесс доступа к памяти. Поэтому между полями записи могут быть пустые байты. Если это недопустимо (например, нужна совместимость с Си), то вместо record используется packed record.
← →
Гошик Кувшинов (2006-02-03 10:27) [7]
> В Паскале поля записей размещаются по адресу, кратному 4
> (на 32-битных машинах).
извините конечно но это не от машины зависит, а от дельфей и настроек. в 7ой дельфе по дефолту выравнивается на 8 байт а не на 4, хотя можно поменять, ищи в меню проект/оптионс на закладке компилер
← →
palva © (2006-02-03 11:56) [8]> я долго мучался с этой проблемой, пытаясь добиться размера в 149, но так ничего и не получилось.
А если поставить новое целое поле в начало записи? Если порядок полей не важен, то можно поэкспериментировать с порядком:
TArea4 = record
Tag : Integer;
...
Temp1 : array [0..14 -4] of Byte;
← →
TUser © (2006-02-03 13:31) [9]
> Гошик Кувшинов (03.02.06 10:27) [7]
type
TA = record
I1: integer;
I2: integer;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption:=inttostr(sizeof(TA));
end;
Выдает 8, как и ожидалось. То, что зависит от компилятора, - это, разумеется, так. Delphi32 выравнивает на 4 байта.
← →
Гошик Кувшинов (2006-02-03 13:47) [10]TUser:
> Delphi32 выравнивает на 4 байта.
я же говорю, от версии зависит. кажется до семёрки все выравнивают на 4, а в семёрке можно выровнять на 1, 2, 4 и 8. там в настройках компилятора комбобокс такой есть. и директивы. вот прямо из справки
Type Switch
Syntax {$A+}, {$A-}, {$A1}, {$A2}, {$A4}, or {$A8}
{$ALIGN ON}, {$ALIGN OFF}, {$ALIGN 1}, {$ALIGN 2}, {$ALIGN 4}, or {$ALIGN 8}
Default {$A8}
{$ALIGN 8}
Scope Local
Remarks
The $A directive controls alignment of fields in Delphi record types and class structures.
In the {$A1} or {$A-} state, fields are never aligned. All record and class structures are packed.
In the {$A2} state, fields in record types that are declared without the packed modifier and fields in class structures are aligned on word boundaries.
In the {$A4} state, fields in record types that are declared without the packed modifier and fields in class structures are aligned on double-word boundaries.
In the {$A8} or {$A+} state, fields in record types that are declared without the packed modifier and fields in class structures are aligned on quad word boundaries.
Record type field alignment is described in the Delphi Language Guide. See Record types.
Regardless of the state of the $A directive, variables and typed constants are always aligned for optimal access. In the {$A8} state, execution will be faster.
← →
Piter © (2006-02-03 14:21) [11]Удалено модератором
Примечание: failed
← →
palva © (2006-02-03 16:10) [12]Я понимаю так, что цитирование хелпа лишь вводит в заблуждение.
Когда пишут "fields in class structures are aligned on word boundaries", то наверно имеют ввиду, что поле является типом Word или что-то еще. Потому что для Char это просто неверно. Давайте лучше обсудим, как это работает НА САМОМ ДЕЛЕ. А на самом деле байты не выравниваются, Word выравниваются на границу слова, Integer на границу двойного слова. По-моему так. Вот пример. Я не пробовал выводить смещения, но размеры записей я напечатал.
{$APPTYPE CONSOLE}
type
r1 = record
w: Word; // 0
i1: Integer; // 4
c: Char; // 8
i2: Integer; // 12
end;
r2 = record
i1: Integer; // 0
c: Char; // 4
w: Word; // 6
i2: Integer; // 8
end;
begin
WriteLn(SizeOf(r1)); // 16
WriteLn(SizeOf(r2)); // 12
end.
Что же касается сабжа (подгонки длины записи), то ее можно осуществить перестановкой полей. Но, видимо, для автора важен порядок полей, в таком случае не знаю, как.
← →
Приятель (2006-02-04 05:47) [13]А если я сделаю Tag не как Integer, а как SmallInt, то подогнать будет можно? Или тоже нельзя?
← →
palva © (2006-02-04 11:26) [14]Я не знаю. Вы сообщаете недостаточно данных о том что можно модифицировать в описании вашей записи. Например, когда вы пытаетесь вставить Tag перед Temp1, у вас изменяется смещение Temp1. Значит у некоторых полей изменять смещение можно, а может быть и требуется по вашему замыслу. И в то же время вы пишете "Учтите, что поля в рекорде не должны смещаться"
← →
palva © (2006-02-04 11:43) [15]Вот например, такая вещь вас устроит?
Temp1 : array [0..14 -4] of Byte;
Tag : Integer;
← →
sniknik © (2006-02-04 11:58) [16]не пойму чего так долго обсуждать? еще в [1] ответ дан. убрать выравнивание и все, и в следующий раз быть внимательнее к этому.
а по нынешней ситуации... придется изучить получающуюся структуру с выравниванием и с убранной сделать выравнивание самому - переменные пустышки навставлять вот и будет "поля в рекорде не должны смещаться", а и не будут.
ведь ясно же что при автоматическом выравнивании не сделать половину рекорда простой, а половину packed (но можно попробовать сделать составной. но тут обращения поменяются... проше руками в одном месте исправить чем по всему проекту).
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2006.02.19;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.042 c