Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2011-04

How to get the offset of a record

11 messages · 6 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Rainer Stratmann

In Turbopascal it was possible with offs()

type
 rectype = record
  var1 : longint;
  var2 : longint;
  var3 : boolean;
 end;
var
 o : longint;
 recvar : rectype;
 o := offs( recvar.var1 );  // --> 0
 o := offs( recvar.var2 );  // --> 4
 o := offs( recvar.var3 );  // --> 8
Aleksa Todorovic
to Rainer Stratmann
Rainer Stratmann wrote 16 lines
In Turbopascal it was possible with offs() type  rectype = record  var1 : longint;  var2 : longint;  var3 : boolean;  end; var  o : longint;  recvar : rectype;  o := offs( recvar.var1 );  // --> 0  o := offs( recvar.var2 );  // --> 4  o := offs( recvar.var3 );  // --> 8
o := PtrUInt( @recvar.var1 ) - PtrUInt( @recvar );
o := PtrIUnt( @recvar.var2 ) - PtrUInt( @recvar );
o := PtrInUt( @recvar.var3 ) - PtrUInt( @recvar );
_______________________________________________ fpc-pascal maillist  -   http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Florian Klämpfl
to Aleksa Todorovic
o := PtrUInt( @recvar.var1 ) - PtrUInt( @recvar ); o := PtrIUnt( @recvar.var2 ) - PtrUInt( @recvar ); o := PtrInUt( @recvar.var3 ) - PtrUInt( @recvar );

Actually even
o := PtrUInt(@(rectype(nil^).var1)));
is possible.

Rainer Stratmann
to Aleksa Todorovic: On Sat, Apr 30, 2011 at 14:30, Rainer Stratmann o := PtrUInt( @recvar.var1 ) - PtrUInt(…
Aleksa Todorovic wrote 23 lines
On Sat, Apr 30, 2011 at 14:30, Rainer Stratmann wrote: > In Turbopascal it was possible with offs() > > type >  rectype = record >  var1 : longint; >  var2 : longint; >  var3 : boolean; >  end; > > var >  o : longint; >  recvar : rectype; > >  o := offs( recvar.var1 );  // --> 0 >  o := offs( recvar.var2 );  // --> 4 >  o := offs( recvar.var3 );  // --> 8 o := PtrUInt( @recvar.var1 ) - PtrUInt( @recvar ); o := PtrIUnt( @recvar.var2 ) - PtrUInt( @recvar ); o := PtrInUt( @recvar.var3 ) - PtrUInt( @recvar );
var addrx : longint;
type
 rectype = record
  var1 : longint;
  var2 : longint;
  var3 : boolean;
 end;
 rectype_2 = record
  ofs1 : longint;
  ofs2 : longint;
  ofs3 : longint;
 end;
var
 recvar : rectype;
procedure t;
var o1 , o2 , o3 : longint;
begin
 // works
 o1 := ptruint( @recvar.var1 ) - ptruint( @recvar );
 o2 := ptruint( @recvar.var2 ) - ptruint( @recvar );
 o3 := ptruint( @recvar.var3 ) - ptruint( @recvar );
end;
const rec : rectype_2 = (
 // does not work! (illegal expression)
 ofs1 : ptruint( @recvar.var1 ) - ptruint( @recvar );
 ofs2 : ptruint( @recvar.var2 ) - ptruint( @recvar );
 ofs3 : ptruint( @recvar.var3 ) - ptruint( @recvar );
 );
Show quoted text 7 lines
> _______________________________________________ > fpc-pascal maillist  -   > http://lists.freepascal.org/mailman/listinfo/fpc-pascal _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jonas Maebe
to Rainer Stratmann: In Turbopascal it was possible with offs() type rectype = record var1 : longint; var2 :…
Rainer Stratmann wrote 14 lines
In Turbopascal it was possible with offs() type rectype = record var1 : longint; var2 : longint; var3 : boolean; end; var o : longint; recvar : rectype; o := offs( recvar.var1 ); // --> 0

That's incorrect. In TP, Ofs(recvar.var1) (with one "f") returns the offset in the segment that contains the "recvar" variable. It does not return the relative offset of the field inside the record type.

Jonas

Rainer Stratmann
to Jonas Maebe
Jonas Maebe wrote 19 lines
On 30 Apr 2011, at 14:30, Rainer Stratmann wrote: > In Turbopascal it was possible with offs() > > type > rectype = record > var1 : longint; > var2 : longint; > var3 : boolean; > end; > > var > o : longint; > recvar : rectype; > > o := offs( recvar.var1 ); // --> 0 That's incorrect. In TP, Ofs(recvar.var1) (with one "f") returns the offset in the segment that contains the "recvar" variable. It does not return the relative offset of the field inside the record type.

That are 2 different things.

There was a function which gives the relative offset of the field I am very sure of that. And I am very sure that it was offs (wich 2 "f").

Jonas_______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Jonas Maebe
to Rainer Stratmann
Rainer Stratmann wrote 9 lines
Am Saturday 30 April 2011 15:16:08 schrieb Jonas Maebe: > That's incorrect. In TP, Ofs(recvar.var1) (with one "f") returns the offset > in the segment that contains the "recvar" variable. It does not return the > relative offset of the field inside the record type. That are 2 different things. There was a function which gives the relative offset of the field I am very sure of that. And I am very sure that it was offs (wich 2 "f").

I'm quite sure it's not, see attachment. The only thing that existed was the "offset" operator, but it only worked in assembler blocks (and afaik it also works in FPC assembler blocks).

Jonas

Rainer Stratmann
to Jonas Maebe
Jonas Maebe wrote 17 lines
On 30 Apr 2011, at 15:20, Rainer Stratmann wrote: > Am Saturday 30 April 2011 15:16:08 schrieb Jonas Maebe: >> That's incorrect. In TP, Ofs(recvar.var1) (with one "f") returns the >> offset in the segment that contains the "recvar" variable. It does not >> return the relative offset of the field inside the record type. > > That are 2 different things. > > There was a function which gives the relative offset of the field I am > very sure of that. And I am very sure that it was offs (wich 2 "f"). I'm quite sure it's not, see attachment. The only thing that existed was the "offset" operator, but it only worked in assembler blocks (and afaik it also works in FPC assembler blocks). Jonas

Hello Jonas,

then it was the offset() method or somehow else... But it was possible.

Ludo Brands
to Jonas Maebe: I'm quite sure it's not, see attachment. The only thing that existed was the "offset"…

This is ages ago, but IIRC getmem would allocate memory on segment boundaries (offset 0). In a dynamically allocated record ofs(record.member) (one f) would give you the offset to the start of record. This was obviously a special case. I'm not sure if large/huge memory model was part of it. Otherwise, conceptually, I can't imagine a function that would return an offset to the start of a structure by only giving a reference to a member of that structure. Even Florians solution contains the starting point: nil.

Ludo

Earlier message 28 lines
-----Message d'origine----- De : De la part de Jonas Maebe Envoyé : samedi 30 avril 2011 15:28 À : FPC-Pascal users discussions Objet : Re: [fpc-pascal] How to get the offset of a record On 30 Apr 2011, at 15:20, Rainer Stratmann wrote: > Am Saturday 30 April 2011 15:16:08 schrieb Jonas Maebe: >> That's incorrect. In TP, Ofs(recvar.var1) (with one "f") returns the >> offset in the segment that contains the "recvar" variable. It does >> not return the relative offset of the field inside the record type. > > That are 2 different things. > > There was a function which gives the relative offset of the field I am > very > sure of that. And I am very sure that it was offs (wich 2 "f"). I'm quite sure it's not, see attachment. The only thing that existed was the "offset" operator, but it only worked in assembler blocks (and afaik it also works in FPC assembler blocks). Jonas
Mark Morgan Lloyd
to Jonas Maebe: That's incorrect. In TP, Ofs(recvar.var1) (with one "f") returns the offset in the…
Jonas Maebe wrote 18 lines
On 30 Apr 2011, at 14:30, Rainer Stratmann wrote: > In Turbopascal it was possible with offs() > > type > rectype = record > var1 : longint; > var2 : longint; > var3 : boolean; > end; > > var > o : longint; > recvar : rectype; > > o := offs( recvar.var1 ); // --> 0 That's incorrect. In TP, Ofs(recvar.var1) (with one "f") returns the offset in the segment that contains the "recvar" variable. It does not return the relative offset of the field inside the record type.

But in at least some cases Ofs() was normalised to always contain 0..15, so it would be easy to (mis)interpret it as an offset into an allocated block.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]