Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
15-1138346057
Nic
2006-01-27 10:14
2006.02.19
Отращиваете ли вы бороду?


2-1138550619
13
2006-01-29 19:03
2006.02.19
ActionMainMenuBar


3-1135332668
Andry
2005-12-23 13:11
2006.02.19
Поле memo и поиск без учета регистра


3-1135683626
WG
2005-12-27 14:40
2006.02.19
Corrupt MEMO/BLOB file - нет ли кода/утилитки для лечения ?


15-1138594840
vidiv
2006-01-30 07:20
2006.02.19
Вопрос по MySQL: LEFT JOIN и RIGHT JOIN





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский