### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Type helper does not work  (Read 1518 times)

#### Nitorami

• Sr. Member
• Posts: 392
##### Type helper does not work
« on: November 22, 2020, 09:01:34 pm »
Can someone explain please why type helper "sub" only works when applied to an explicitly declared variable but not on a function result which returns the same type of pointer ?

Code: Pascal  [Select][+][-]
2. {\$modeswitch typehelpers}
3.
4. type float = double;
5.      pfloat = ^float;
6.
7. type  TFloathelper = type helper for float
8.         procedure sub (const a: float);
9.       end;
10.
11. type TMatrix = record
12.                  sx,sy: sizeint;
13.                  procedure Init (x,y: sizeint; content: array of float);
14.                  function GetAdr (x,y: sizeint): pfloat;
15.                  procedure print;
16.                  private
17.                    data: array of float;
18.                end;
19.
20. procedure TFloatHelper.sub (const a: float);
21. begin
22.   self := self-a;
23. end;
24.
25. function TMatrix.GetAdr (x,y: sizeint): pfloat;
26. begin
27.   result := @data[x*sy+y];
28. end;
29.
30. procedure TMatrix.Init (x,y: sizeint; content: array of float);
31. var i: sizeint;
32. begin
33.   sx :=x;
34.   sy :=y;
35.   Data := nil;
36.   SetLength (data, sx*sy);
37.   for i := 0 to sx*sy-1 do data[i] := content[i];
38. end;
39.
40. procedure TMatrix.print;
41. var x,y: sizeint;
42. begin
43.   for y := 0 to sy-1 do begin
44.     writeln;
45.     for x := 0 to sx-1 do begin
47.     end;
48.   end;
49.   writeln;
50. end;
51.
52. var A: TMatrix;
53.     px: pfloat;
54. begin
55.   A.Init (2,2,[1,2,3,4]);
56.   A.print;
57.
58.   A.GetAdr(1,1)^ := 0; //I can set an element like this...
59.   A.Print;
60.
62.   px^.sub(100);  //and this works as well.
63.   A.Print;
64.
65.   A.GetAdr(1,1)^.sub(1000); //but that does not change the Matrix !?!
66.   A.print;
67. end.
68.

EDIT: FPC 3.2.0, win32
« Last Edit: November 22, 2020, 09:10:38 pm by Nitorami »

#### jamie

• Hero Member
• Posts: 4039
##### Re: Type helper does not work
« Reply #1 on: November 23, 2020, 01:30:21 am »
I would say you found a bug

At first glance it looks ok and should work but it appears it must be using a cached float instead of the original.

I guess I could copy and paste that code to see if it fails here with older Fpc.
The only true wisdom is knowing you know nothing

#### jamie

• Hero Member
• Posts: 4039
##### Re: Type helper does not work
« Reply #2 on: November 23, 2020, 01:44:26 am »
Yes, I just debugged it..

Its using RAX as an indirect load of the float into RAX and then stores it on the stack.
RAX points to the float but it is being used as a load indirect instead.

when SUB comes along, it only modifies the stack object.

The only true wisdom is knowing you know nothing

#### PascalDragon

• Hero Member
• Posts: 2595
• Compiler Developer
##### Re: Type helper does not work
« Reply #3 on: November 23, 2020, 01:47:44 pm »

#### Nitorami

• Sr. Member
• Posts: 392
##### Re: Type helper does not work
« Reply #4 on: November 23, 2020, 06:21:12 pm »
Thanks for looking into that.
Issued bug report 0038122.

#### jamie

• Hero Member
• Posts: 4039
##### Re: Type helper does not work
« Reply #5 on: November 24, 2020, 12:26:08 am »
Code: Pascal  [Select][+][-]
1. program Project1;
2.
3. {\$mode objfpc}{\$H+}
5. {\$modeswitch typehelpers}
6.
7. type float = double;
8.      pfloat = ^float;
9.
10. type  TFloathelper = type helper for pfloat
11.         procedure sub (const a: float);
12.       end;
13.
14. type TMatrix = record
15.                  sx,sy: sizeint;
16.                  procedure Init (x,y: sizeint; content: array of float);
17.                  function GetAdr (x,y: sizeint): pfloat;
18.                  procedure print;
19.                  private
20.                    data: array of float;
21.                end;
22.
23. Procedure TFloatHelper.sub (const a: float);
24. begin
25.   self^ := self^-a;
26. end;
27.
28. function TMatrix.GetAdr (x,y: sizeint): pfloat;
29. begin
30.   result := @data[x*sy+y];
31. end;
32.
33. procedure TMatrix.Init (x,y: sizeint; content: array of float);
34. var i: sizeint;
35. begin
36.   sx :=x;
37.   sy :=y;
38.   Data := nil;
39.   SetLength (data, sx*sy);
40.   for i := 0 to sx*sy-1 do data[i] := content[i];
41. end;
42.
43. procedure TMatrix.print;
44. var x,y: sizeint;
45. begin
46.   for y := 0 to sy-1 do begin
47.     writeln;
48.     for x := 0 to sx-1 do begin
50.     end;
51.   end;
52.   writeln;
53. end;
54.
55. var A: TMatrix;
56.     px: pfloat;
57. begin
58.   A.Init (2,2,[1,2,3,4]);
59.   A.print;
60.
61.   A.GetAdr(1,1)^ := 0; //I can set an element like this...
62.   A.Print;
63.
65.   px.sub(100);  //and this works as well.
66.   A.Print;
67.
68.   A.GetAdr(1,1).sub(1000); //but that does not change the Matrix !?!
69.   A.print;
71. end.
72.
73.
74.
The only true wisdom is knowing you know nothing

#### Nitorami

• Sr. Member
• Posts: 392
##### Re: Type helper does not work
« Reply #6 on: November 24, 2020, 05:13:50 pm »
Yes, that works, but in effect the helper now applies to a pointer, and who knows which complications that will bring along ?  I believe it should work the straight way, and am curious how the discussion in Mantis will go on.

#### bytebites

• Sr. Member
• Posts: 367
##### Re: Type helper does not work
« Reply #7 on: December 09, 2020, 09:26:34 am »
Code: Pascal  [Select][+][-]
1. program strhlp;
2. {\$mode delphi}
3. uses sysutils;
4. type trec=record
5.   i:integer;
6.  end;
7.
8.  var rec:trec;
9.      prec:^trec;
10. begin
11.   rec.i:=20;
12.   prec:=@rec;
13.   writeln(prec.i.tostring);
14. end.
15.

String helper does not work. Previously (version 3.2) prints 20 now trunk something else like 4750144
Is this intended change?

#### jamie

• Hero Member
• Posts: 4039
##### Re: Type helper does not work
« Reply #8 on: December 09, 2020, 03:19:33 pm »
You say trunk I assume you are referring to the compiler 3.3.x?

If that being the case, please report it.

what you have there should work indeed.
The only true wisdom is knowing you know nothing

#### ASerge

• Hero Member
• Posts: 1711
##### Re: Type helper does not work
« Reply #9 on: December 09, 2020, 03:26:27 pm »
String helper does not work. Previously (version 3.2) prints 20 now trunk something else like 4750144
Is this intended change?
Revision 47611 (fpc 3.3.1) prints 20.

#### bytebites

• Sr. Member
• Posts: 367
##### Re: Type helper does not work
« Reply #10 on: December 09, 2020, 04:23:36 pm »
Revision 47737 and result is 4736896

#### rvk

• Hero Member
• Posts: 4452
##### Re: Type helper does not work
« Reply #11 on: December 09, 2020, 05:09:12 pm »
Revision 47737 and result is 4736896
Confirmed.

It seems to prints the memory location of rec instead of the value of i with ToString.
Last change in syshelpo.inc is 45370 (may 15th 2020).

But if ASerge says it prints 20 in 47611 it couldn't be in there.

#### Nitorami

• Sr. Member
• Posts: 392
##### Re: Type helper does not work
« Reply #12 on: December 09, 2020, 05:12:52 pm »
Uh oh.

I had reported bug 0038122 on this issue. Sven Barth took over and agreed this should be fixed, fixed it and asked me to test and then close the issue. I tested with with fpc 3.3.1 as of 29.11. (rev. 47629) and it was ok so I closed the issue.

But I can replicate your problem with exactly this fpc version, so it looks indeed as if the bug had been introduced when resolving the original issue. Can you please issue a bug report with reference to #0038122 ? Otherwise I will re-open my report.

#### bytebites

• Sr. Member
• Posts: 367
##### Re: Type helper does not work
« Reply #13 on: December 09, 2020, 05:29:05 pm »