Recent

Author Topic: Something is wrong with this code, but I can't decide what it is  (Read 1462 times)

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Code: Pascal  [Select][+][-]
  1. program app;
  2. {$modeswitch anonymousfunctions}
  3.  
  4. type
  5.   TMyProc = procedure (value: NativeInt);
  6.  
  7. procedure Test(const anonproc);
  8. begin
  9.   TMyProc(@anonproc)(33);
  10. end;
  11.  
  12. procedure Run;
  13. begin
  14.   Test(procedure (value: NativeInt)
  15.        begin
  16.          WriteLn('Anon value = ', value);
  17.        end);
  18. end;
  19.  
  20. begin
  21.   Run;
  22.   ReadLn;
  23. end.

Output (x86_64) (can be a random value, on Linux a different value):
Code: [Select]
2
My options:
  • It should be fixed that in this case arguments are not shifted by 1 as they are now. RCX (x86_64 Windows) is occupied by an implicit argument
  • It is necessary to pass not a pointer to the code, but form a full reference to / $CapturerClass_*
  • Forbid to pass such parameters to such type (D12.1CE does this, but I don't like this idea very much, because possible flexibility is lost)


Fibonacci

  • Hero Member
  • *****
  • Posts: 755
  • Internal Error Hunter
Re: Something is wrong with this code, but I can't decide what it is
« Reply #1 on: May 17, 2025, 01:01:25 pm »
I vote for option 1, but will be fixed with option 3 (easiest), as was done with @<anonfunc> - I was using that syntax >:( @PascalDragon: Made sure that @<anonfunc> is now completely forbidden

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Re: Something is wrong with this code, but I can't decide what it is
« Reply #2 on: May 17, 2025, 01:14:11 pm »
Although... for some reason I didn't think of it right away. but this code is fixed like this, so maybe it's not a problem at all? )

Code: Pascal  [Select][+][-]
  1. program app;
  2. {$modeswitch anonymousfunctions}
  3.  
  4. type
  5.   TMyProc = procedure (value: NativeInt) of object;
  6.  
  7. procedure Test(const anonproc);
  8. var
  9.   m: TMethod;
  10. begin
  11.   m.Code:=@anonproc;
  12.   TMyProc(m)(33);
  13. end;
  14.  
  15. procedure Run;
  16. begin
  17.   Test(procedure (value: NativeInt)
  18.        begin
  19.          WriteLn('Anon value = ', value);
  20.        end);
  21. end;
  22.  
  23. begin
  24.   Run;
  25.   ReadLn;
  26. end.

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Re: Something is wrong with this code, but I can't decide what it is
« Reply #3 on: May 17, 2025, 01:28:22 pm »
@<anonfunc> - I was using that syntax
...
Made sure that @<anonfunc> is now completely forbidden[/url][/i]

I'm a little confused about your message

You can do that:
Code: Pascal  [Select][+][-]
  1. program app;
  2. {$modeswitch anonymousfunctions}
  3.  
  4. type
  5.   TProc = procedure(value: NativeInt);
  6.  
  7. procedure Test2(anonproc: TProc);
  8. begin
  9.   anonproc(55);
  10. end;
  11.  
  12. begin
  13.   Test2(procedure(value: NativeInt)
  14.         begin
  15.           WriteLn(value);
  16.         end);
  17.   ReadLn;
  18. end.

Is there anything wrong with that option?

Fibonacci

  • Hero Member
  • *****
  • Posts: 755
  • Internal Error Hunter
Re: Something is wrong with this code, but I can't decide what it is
« Reply #4 on: May 17, 2025, 01:43:39 pm »
I had a specific use case where a procedure accepted few different anon functions (different arg types, arg count) which were used to set them as callbacks, it worked fine.

Something like
Code: Pascal  [Select][+][-]
  1. blahblah('something', @(procedure(a: string; b: integer) begin
  2.   // ...
  3. end),
  4.   ['xaxa', 1337]
  5. );
« Last Edit: May 17, 2025, 01:56:37 pm by Fibonacci »

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Re: Something is wrong with this code, but I can't decide what it is
« Reply #5 on: May 17, 2025, 02:35:40 pm »
In general, I originally wanted to do this kind of “convert” an anonymous function into a method

And the fact that now the first argument is passed to RDX is even to my advantage, so I withdraw my wishes :P

I'm happy with everything now, but there is room for discussion, of course :D

Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}
  3. {$modeswitch anonymousfunctions}
  4.  
  5. uses Classes;
  6.  
  7. generic function AnonymToMethod<T>(AObj: Tobject; const AnonProc): T;
  8. begin
  9.   TMethod(Result).Code:=@AnonProc;
  10.   TMethod(Result).Data:=AObj;
  11. end;
  12.  
  13. var
  14.   SL: TStringList;
  15.  
  16. begin
  17.   SL := TStringList.Create;
  18.   SL.OnChange:=specialize AnonymToMethod<TNotifyEvent>(SL,
  19.     procedure (Sender: TObject)
  20.     begin
  21.       WriteLn((Sender as TStringList).Count);
  22.     end);
  23.  
  24.   SL.Add('1');
  25.   SL.Add('2');
  26.   SL.Add('3');
  27.  
  28.   ReadLn;
  29. end.

Fibonacci

  • Hero Member
  • *****
  • Posts: 755
  • Internal Error Hunter
Re: Something is wrong with this code, but I can't decide what it is
« Reply #6 on: May 25, 2025, 03:11:30 pm »
Can someone check if this is allowed in Delphi?

Code: Pascal  [Select][+][-]
  1. {$modeswitch anonymousfunctions}
  2. var
  3.   p: pointer;
  4. begin
  5.   p := @(procedure begin
  6.     writeln('hello');
  7.   end);
  8.   tprocedure(p);
  9.   readln;
  10. end.

This is now forbidden (illegal expression) in FPC, but why?

The problem is that if I use "function references" modeswitch, TCapturer gets into action and my mini-exe, instead of being 6 KB, now becomes 12 KB!

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Re: Something is wrong with this code, but I can't decide what it is
« Reply #7 on: May 25, 2025, 03:47:59 pm »
In D12.1CE it works:

Code: Pascal  [Select][+][-]
  1. program app;
  2.  
  3. type
  4.   TProcedure = reference to procedure;
  5.  
  6. var
  7.   p: pointer;
  8.  
  9. begin
  10.   p := @(procedure begin
  11.     WriteLn('hello');
  12.   end);
  13.   TProcedure(p)();
  14.   ReadLn;
  15. end.
« Last Edit: May 25, 2025, 03:52:59 pm by ALLIGATOR »

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Re: Something is wrong with this code, but I can't decide what it is
« Reply #8 on: May 25, 2025, 03:50:25 pm »
And this doesn't work in FPC[git main]:
Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode delphi}
  3. {$modeswitch anonymousfunctions}
  4. {$modeswitch functionreferences}
  5.  
  6. type
  7.   TProcedure = reference to procedure;
  8.  
  9. var
  10.   p: pointer;
  11.  
  12. begin
  13.   p := @(procedure begin
  14.     WriteLn('hello');
  15.   end);
  16.   TProcedure(p)();
  17.   ReadLn;
  18. end.
« Last Edit: May 25, 2025, 03:53:54 pm by ALLIGATOR »

Fibonacci

  • Hero Member
  • *****
  • Posts: 755
  • Internal Error Hunter
Re: Something is wrong with this code, but I can't decide what it is
« Reply #9 on: May 25, 2025, 03:55:25 pm »
Without the reference works too?

Code: Pascal  [Select][+][-]
  1. program app;
  2.  
  3. type
  4.   TProcedure = procedure;
  5.  
  6. var
  7.   p: pointer;
  8.  
  9. begin
  10.   p := @(procedure begin
  11.     WriteLn('hello');
  12.   end);
  13.   TProcedure(p)();
  14.   ReadLn;
  15. end.

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Re: Something is wrong with this code, but I can't decide what it is
« Reply #10 on: May 25, 2025, 07:00:15 pm »
compiles but doesn't work

Fibonacci

  • Hero Member
  • *****
  • Posts: 755
  • Internal Error Hunter
Re: Something is wrong with this code, but I can't decide what it is
« Reply #11 on: May 25, 2025, 07:01:43 pm »
Ok, thanks for testing

Thaddy

  • Hero Member
  • *****
  • Posts: 17198
  • Ceterum censeo Trump esse delendam
Re: Something is wrong with this code, but I can't decide what it is
« Reply #12 on: May 26, 2025, 10:22:27 am »
TProcedure is already declared in system, so do not redeclare it as its reference.....
https://www.freepascal.org/docs-html/rtl/system/tprocedure.html
Maybe the code will work if you declare the reference as TProcedureRef instead of Tprocedure?
Can' t test now. But it is the case in both Delphi 12.1 and FPC.
« Last Edit: May 26, 2025, 10:34:49 am by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

ALLIGATOR

  • Full Member
  • ***
  • Posts: 181
Re: Something is wrong with this code, but I can't decide what it is
« Reply #13 on: May 26, 2025, 11:20:30 am »
.

440bx

  • Hero Member
  • *****
  • Posts: 5477
Re: Something is wrong with this code, but I can't decide what it is
« Reply #14 on: May 26, 2025, 11:43:42 am »
@ALLIGATOR,

if I may ask, what font are you using ?

Thank you in advance.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v4.0rc3) on Windows 7 SP1 64bit.

 

TinyPortal © 2005-2018