powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Смещение поля записи в константы
22 сообщений из 22, страница 1 из 1
Смещение поля записи в константы
    #39707962
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такая запись
Код: pascal
1.
2.
3.
4.
TMyRec = record
  A: Boolean;
  B: Boolean;
end;


Хочу в константах получить смещения полей. Пишу

Код: pascal
1.
2.
3.
4.
5.
type
  PMyRec = ^TMyRec;
const
  PA = @PMyRec(nil).A;
  PB = @PMyRec(nil).B;


PA объявляется. При объявлении PB получаю ошибку[dcc32 Error] E2026 Constant expression expected
Как-то можно извернуться? Ручное вычисление смещения пока не рассматриваю


С уважением, Vasilisk
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39707963
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Немного ошибся. В коде так
Код: pascal
1.
2.
  PA = @PMyRec(nil)^.A;
  PB = @PMyRec(nil)^.B;

но ошибка та же
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39707966
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смешение у такой структуры будет ровна предыдущим элементам.


Что означает, что самый главный адрес указывает на первый элемент A.
Для получения второго элемента NativeUInt(Address) + SizeOf(Boolean) от первого элемента Boolean
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39707971
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГирлионайльдоСмешение у такой структуры будет ровна предыдущим элементам.+ выравнивание . Именно поэтому_Vasilisk_Ручное вычисление смещения пока не рассматриваю
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39707974
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока получилось так

Код: pascal
1.
2.
3.
4.
const
  CMyRec: TMyRec = ();
  PA: Pointer = @CMyRec.A;
  PB: Pointer = @CMyRec.B;


Объявление типизированных констант обязательно.

Ну а в коде уже от этих констант отнимаю базовый адрес @CMyRec
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39707975
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
_Vasilisk_Есть такая запись
Код: pascal
1.
2.
3.
4.
TMyRec = record
  A: Boolean;
  B: Boolean;
end;



Хочу в константах получить смещения полей. Пишу

Код: pascal
1.
2.
3.
4.
5.
type
  PMyRec = ^TMyRec;
const
  PA = @PMyRec(nil).A;
  PB = @PMyRec(nil).B;



PA объявляется. При объявлении PB получаю ошибку[dcc32 Error] E2026 Constant expression expected
Как-то можно извернуться? Ручное вычисление смещения пока не рассматриваю
никак, только вручную
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708020
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Именно у той структуры, которую ты привёл - не будет никакого выравнивания.
Потому как ты не упомянул в ней packed

А ошибка в твоём случае именно потому, что ты у nil данных пытаешься прочитать адреса по смещению (где никак таких данных нет)

Т.е, что бы узнать смещения, а оно как я напомню, начинается от главного адреса, нам надо произвести такой банальный код
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  TMyRec = record
    A: Boolean;
    str: string;
    B: Boolean;
    d: Double;
  end;

var
  r: TMyRec;
  BaseAddres: NativeUInt;

procedure printaddr(name: string; p: pointer);
begin
  Writeln(name, ': [', NativeUInt(p), '] ', (NativeUInt(p) - BaseAddres));
end;

begin
  BaseAddres := NativeUInt(@r);
  printaddr('BaseAddres', @r);
  with r do
  begin
    A := false;
    printaddr('A: Boolean', @A);
    str := 'Text 1924';
    printaddr('str: string', @str);
    B := true;
    printaddr('B: Boolean', @B);
    d := 46.46;
    printaddr('d: Double', @d);
  end;
  Readln;

end.



Код: sql
1.
2.
3.
4.
5.
BaseAddres: [4348088] 0
A: Boolean: [4348088] 0
str: string: [4348092] 4
B: Boolean: [4348096] 8
d: Double: [4348104] 16
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708021
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вот у упакованной структуры, смещения будут такие

Код: sql
1.
2.
3.
4.
5.
BaseAddres: [4348088] 0
A: Boolean: [4348088] 0
str: string: [4348089] 1
B: Boolean: [4348093] 5
d: Double: [4348094] 6
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708023
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ГирлионайльдоА ошибка в твоём случае именно потому, что ты у nil данных пытаешься прочитать адреса по смещению (где никак таких данных нет)
Няшка, жги!!!
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708025
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Гирлионайльдо_Vasilisk_,

Именно у той структуры, которую ты привёл - не будет никакого выравнивания.
Потому как ты не упомянул в ней packed
смещения будут в любом случае, packed или не packed
но ты жги, да
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708054
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_,

Что так? такая жёсткая экономия памяти? Будет кода больше imho
Сделай integer и работай с маской а не с запясью.
И совместимость и переносимость выше again-imho
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708123
AWSVladimir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorГирлионайльдо_Vasilisk_,

Именно у той структуры, которую ты привёл - не будет никакого выравнивания.
Потому как ты не упомянул в ней packed
смещения будут в любом случае, packed или не packed
но ты жги, да

Он про выравнивание, а не про смещение.

Гирлионайльдо, ты прав с точночтью до наоборот.
Отличие record от record packed:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
TRec=record   
  b:byte;
  i:integer
end;
 TRecPack=record packed  
  b:byte;
  i:integer
end;



TRecPack - SizeOf = 5 байт,
TRec - SizeOf = ХЗ байт, как компилятор на душу положит, как раз из-за выравнивания адресов для процессора.
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708511
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GatorЧто так? такая жёсткая экономия памяти?Нет. Пишу для структуры простенький сериализатор/десериализатор. Не хочется что-то забыть при будущем добавлении полей. А так адреса забил в константный массив и отдаю его сериализатору.

RTTI тут использовать не к месту
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708537
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для тех, кто любит грабли, мазохизм и прочую экзотику:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
type
  PMyRec = ^TMyRec;
  TMyRec = record
    A: Byte;
    B: Integer;
  end;

const
  PB: Integer = 0; // смещение поля В от начала записи

....

initialization
  PInteger(@PB)^ := Integer(@TMyRec(nil^).B);  
....
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708561
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Пишу для структуры простенький сериализатор/десериализатор. Не хочется что-то забыть при будущем добавлении полей. А так адреса забил в константный массив и отдаю его сериализатору.

RTTI тут использовать не к месту

Как мне кажется, RTTI именно для таких случаев уместно.
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39708936
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_GatorЧто так? такая жёсткая экономия памяти?Нет. Пишу для структуры простенький сериализатор/десериализатор. Не хочется что-то забыть при будущем добавлении полей. А так адреса забил в константный массив и отдаю его сериализатору.

RTTI тут использовать не к местуМне кажется, тут не RTTI, а оргмеры нужны.
Представь, если не совпадают версии исходной структуры и и вайла со смещениями (описания) структуры.
Ясен пень смещения могут лететь. Даже если поля постоянной длины и есть условия.

В свое время делали разбор тикетов и писали на сях UDF (User Definition Format)
Там исходный тикет содержал бинарные переменной длины поля, флаги, или размеры, версии и прочую мутотень.
UDF (INIфайл по сути - xml тогда не было) содержал описание каждого поля, условия и прочую нужную фигню. Даже COMMENT= был
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39709123
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы не забыть поменять код при добавлении полей, можно использовать такое:
Код: pascal
1.
{$IF Sizeof(TMyRec) <> ExpectedSize}Achtung! Razmeren zapisen nicht sovpadaitung!{$IFEND}


Я такое местами делаю в enum-ах, если на них завязаны какие-то еще данные.
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39709596
rtticycle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_Как-то можно извернуться?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
  TFildOffsets = class
    type TOffsets = array of Integer;
    procedure Add(aOffset:Integer; var aOffsets:TOffsets);
    procedure Fild(var aFild:Integer; var aOffsets:TOffsets); overload;
    procedure Fild(var aFild:Double;  var aOffsets:TOffsets); overload;
  end;

  TFilds = class(TFildOffsets)
    A : Integer;
    D : Double;
    class var Offsets:TFildOffsets.TOffsets;
    class constructor Init;
  end;

{ TFildOffsets }

procedure TFildOffsets.Add(aOffset: Integer; var aOffsets: TOffsets);
begin
  SetLength(aOffsets, Length(aOffsets)+1);
  aOffsets[Length(aOffsets)-1] := aOffset;
end;

procedure TFildOffsets.Fild(var aFild: Integer; var aOffsets: TOffsets);
begin
  Add(PByte(@aFild) - PByte(Self), aOffsets);
end;

procedure TFildOffsets.Fild(var aFild: Double; var aOffsets: TOffsets);
begin
  Add(PByte(@aFild) - PByte(Self), aOffsets);
end;

{ TFilds }

class constructor TFilds.Init;
begin
  with TFilds(nil) do begin
    Fild(A, Offsets);
    Fild(D, Offsets);
  end;
end;

Подсластить, добавить версионность и вкушать у камина.
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39709862
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rtticycle
Код: pascal
1.
TFilds = class(TFildOffsets)

Так и я могу. В вопросе речь шла о record. А он классовых конструкторов не умеет
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39709871
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_В вопросе речь шла о record. А он классовых конструкторов не умеет
Умеет.
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39709872
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyУмеет.Прикольно! Не знал. Тогда вопрос снят
...
Рейтинг: 0 / 0
Смещение поля записи в константы
    #39710278
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_, всё равно это не снимает вопрос соответствия структуры обрабатываемых даннык и класса- обработчика
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Смещение поля записи в константы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]