Recent

Author Topic: Is there a function/operator in FPC that returns the offset of a field ?  (Read 5941 times)

440bx

  • Hero Member
  • *****
  • Posts: 4024
Hello,

given something like:
Code: Pascal  [Select][+][-]
  1. type
  2.   TSomeRecord = record
  3.     FirstField       : word;
  4.     SecondField      : byte;
  5.     ThirdField       : qword;
  6.   end;
  7.  

is there an "offset" function/operator that would directly return the offset of any one field in the above record ?  for instance, offset(TSomeRecord.ThirdField) would return 8 (because of alignment.)

It is easy to calculate the offset as the difference of two pointers but, it would sure be nice if there is a direct way of getting it.  That's my question, is there such a nice way of getting a field's offset ?

Thank you for your help.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14371
  • Sensorship about opinions does not belong here.
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #1 on: November 12, 2018, 07:20:50 am »
Afaik only like this, as you already observed:
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode delphi}{$H-}{$endif}
  2.  
  3. type
  4.   TSomeRecord1 = packed record
  5.     FirstField       : word;
  6.     SecondField      : byte;
  7.     ThirdField       : qword;
  8.   end;
  9.  
  10.   TSomeRecord2 = record
  11.     FirstField       : word;
  12.     SecondField      : byte;
  13.     ThirdField       : qword;
  14.   end;
  15.  
  16. var R1: TSomeRecord1;
  17.     R2: TSomeRecord2;
  18. begin
  19.  writeln(Addr(R1.ThirdField) - Addr(R1)); //3  
  20.  writeln(Addr(R2.ThirdField) - Addr(R2)); //8 , depending on alignment settings)
  21. end.
[/code]
« Last Edit: November 12, 2018, 07:26:14 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

440bx

  • Hero Member
  • *****
  • Posts: 4024
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #2 on: November 12, 2018, 07:25:44 am »
Afaik only like this, as you already observed:
Code: Pascal  [Select][+][-]
  1. {$ifdef fpc}{$mode delphi}{$H-}{$endif}
  2. type
  3.   TSomeRecord = record
  4.     FirstField       : word;
  5.     SecondField      : byte;
  6.     ThirdField       : qword;
  7.   end;
  8.  
  9. var R: TSomeRecord;
  10. begin
  11.  writeln(Addr(R.ThirdField) - Addr(R));  
  12. end.
Thanks Thaddy.  I was afraid that would be the answer but, I figured I'd ask just in case. 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14371
  • Sensorship about opinions does not belong here.
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #3 on: November 12, 2018, 07:27:25 am »
I expect the compiler to use an intrinsic, but it is not public.
In assembler it is no problem.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

PascalDragon

  • Hero Member
  • *****
  • Posts: 5469
  • Compiler Developer
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #4 on: November 12, 2018, 05:12:43 pm »
The following expression might look strange, but we consider it one of the official ways to retrieve the offset to a field ;)

Code: Pascal  [Select][+][-]
  1. PrnUInt(@TSomeRecord(Nil^).ThirdField)

440bx

  • Hero Member
  • *****
  • Posts: 4024
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #5 on: November 12, 2018, 05:40:16 pm »
The following expression might look strange, but we consider it one of the official ways to retrieve the offset to a field ;)

Code: Pascal  [Select][+][-]
  1. PrnUInt(@TSomeRecord(Nil^).ThirdField)

Thank you.  I see what it does.

Definitely an improvement over using pointer difference.

It still cannot be used to define a constant equal to the offset of a field in some record.  If it could be used for that, then it would probably be a full replacement for an offset function.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14371
  • Sensorship about opinions does not belong here.
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #6 on: November 12, 2018, 06:13:24 pm »
That would require an extension of the macro support (the const), since it is align dependent.
Rather nifty reply from Sven... ::)
On second thought: test that!
This works:
Code: Pascal  [Select][+][-]
  1. program untitled;
  2. {$mode objfpc}
  3. type
  4.  TSomerecord = record
  5.  a:integer;
  6.  b:byte;
  7.  c:word;
  8.  end;
  9.  
  10. const
  11.   OffsetC:PtrUint = NativeUint(@TSomeRecord(Nil^).C);
  12. begin
  13.   writeln(OffsetC);
  14. end.
<grin>
« Last Edit: November 12, 2018, 06:28:52 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

440bx

  • Hero Member
  • *****
  • Posts: 4024
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #7 on: November 12, 2018, 06:44:56 pm »
@Thaddy,

The compiler is not happy with your example.  I get an "illegal expression" on the definition of OffsetC.

(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14371
  • Sensorship about opinions does not belong here.
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #8 on: November 12, 2018, 07:09:02 pm »
@Thaddy,

The compiler is not happy with your example.  I get an "illegal expression" on the definition of OffsetC.
Why does it work for me?
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

440bx

  • Hero Member
  • *****
  • Posts: 4024
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #9 on: November 12, 2018, 08:20:33 pm »
Why does it work for me?

I'm using FPC 3.0.4.  What FPC version are you using ?
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14371
  • Sensorship about opinions does not belong here.
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #10 on: November 13, 2018, 08:49:50 am »
3.2.0 and trunk 3.3.1 (daily rolling compile).
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

440bx

  • Hero Member
  • *****
  • Posts: 4024
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #11 on: November 13, 2018, 04:57:10 pm »
3.2.0 and trunk 3.3.1 (daily rolling compile).
That's likely why it works for you and not for me. 
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

guest58172

  • Guest
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #12 on: November 13, 2018, 06:08:22 pm »
suggestions: add a `.OffsetOf` property to aggregate members. Too bad if the member is itself an aggregate type with a member called OffsetOf...
but still doable with a deprecation. 'deprecation: OffsetOf is a reserved identifier inside aggregates'.

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #13 on: November 13, 2018, 11:29:33 pm »
This works for me using 1.8.4/3.0.4

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   caption := PtrUint(@TRect(nil^).top).ToSTring;
  4. end;                                              
  5.  

if you are looking for a built in function to give you an offset I am not sure how much value it would have since we can do it
this way?
« Last Edit: November 13, 2018, 11:43:06 pm by jamie »
The only true wisdom is knowing you know nothing

440bx

  • Hero Member
  • *****
  • Posts: 4024
Re: Is there a function/operator in FPC that returns the offset of a field ?
« Reply #14 on: November 13, 2018, 11:36:16 pm »
This works for me using 1.8.4/3.0.4

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   caption := PtrUint(@TRect(nil^).top).ToSTring;
  4. end;                                              
  5.  
Yes, that works because caption is being assigned at run time instead of compile time.  if you try this:
Code: Pascal  [Select][+][-]
  1. const
  2.   caption : ptruint = PtrUint(@TRect(nil^).top).ToSTring;
  3.  
it won't work in FPC 3.04  (unfortunately)

But, thank you, I appreciate the help.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018