Recent

Poll

Did you know about this?

Yes I did
2 (16.7%)
Nope
10 (83.3%)

Total Members Voted: 12

Author Topic: Magic, non referenced variable changes it's value  (Read 818 times)

Fibonacci

  • New member
  • *
  • Posts: 7
Magic, non referenced variable changes it's value
« on: May 25, 2023, 01:15:06 am »
I was coding today and something strange happened. Somehow at some point part of my string was changed although I wasn't changing it (so I thought...)

Long story short, the string was changed, but by different function, which I didn't pass the variable as pointer or "var s: string"

I quickly came to the conclusion, if function is "inline" then parameters variables are passed as reference/pointer, but not always!

I wrote this POC code to show it in action. The strangest thing is the TWO functions MUST be inlined for the "magic" to happen, why is that? Is this kind of behavior documented somewhere? Some FPC dev shall explain?

Request: I don't have Delphi and I'm curious, please compile this code and post here if the string was replaced to "magic".

Quick poll: did you know about this? I didn't.

Code: Pascal  [Select][+][-]
  1. program magic;
  2.  
  3. procedure test(s: string); inline;
  4. begin
  5.   //this procedure actually does nothing
  6.   //it just changes it's "s" variable (copy of?) to "magic"
  7.   s := 'magic';
  8. end;
  9.  
  10. procedure main; inline;
  11. var
  12.   some_string: string;
  13. begin
  14.   //set some string
  15.   some_string := 'some value';
  16.  
  17.   //call function that "does nothing"
  18.   test(some_string);
  19.  
  20.   //expected "some value", shows "magic"
  21.   writeln(some_string);
  22.  
  23.   readln;
  24. end;
  25.  
  26. begin
  27.   main;
  28. end.

It's not because it's string, it does the same with any type, lets check integer:

Code: Pascal  [Select][+][-]
  1. program magic;
  2.  
  3. procedure test(x: integer); inline;
  4. begin
  5.   x := 1234;
  6. end;
  7.  
  8. procedure main; inline;
  9. var
  10.   int_test: integer;
  11. begin
  12.   //set some integer
  13.   int_test := 555;
  14.  
  15.   //call function that "does nothing"
  16.   test(int_test);
  17.  
  18.   //expected "555", shows "1234"
  19.   writeln(int_test);
  20.  
  21.   readln;
  22. end;
  23.  
  24. begin
  25.   main;
  26. end.
  27.  

Regards
« Last Edit: May 25, 2023, 01:17:41 am by Fibonacci »

Fibonacci

  • New member
  • *
  • Posts: 7
Re: Magic, non referenced variable changes it's value
« Reply #1 on: May 25, 2023, 09:31:40 am »
Compiled in Delphi, different result. Works as expected. So seems like a bug in FPC.

Blaazen

  • Hero Member
  • *****
  • Posts: 3232
  • POKE 54296,15
    • Eye-Candy Controls
Re: Magic, non referenced variable changes it's value
« Reply #2 on: May 25, 2023, 04:02:31 pm »
Report it on GitLab. BTW, I have also opened one ticket about inlining: https://gitlab.com/freepascal.org/fpc/source/-/issues/40158
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

Red_prig

  • Jr. Member
  • **
  • Posts: 99
Re: Magic, non referenced variable changes it's value
« Reply #3 on: May 25, 2023, 04:35:17 pm »
I have seen something similar, so you have to be careful with inline procedures

WooBean

  • Full Member
  • ***
  • Posts: 183
Re: Magic, non referenced variable changes it's value
« Reply #4 on: May 26, 2023, 08:06:36 am »

@Fibonacci
« on: May 25, 2023, 01:15:06 am »

Well, so we have problem when calling inlined procedure inside inlined procedure when this called one (procedure/function) can change parameter(s) declared as value parameter(s). This behaviour of FPC breaks the statement obout parameters: 
"When parameters are declared as value parameters, the procedure gets a copy of the parameters that the calling statement passes. Any modifications to these parameters are purely local to the procedure’s block, and do not propagate back to the calling block."

One more observation, documentation says that inlining is disabled by default and needs  to be activated by directive {$INLINE ON} or commandline switch [-Si]. This option can be set inside Lazarus configuration. Actually (for Lazarus 2.2.0/FPC 3.2.2) inlining is accessible without it (for mode objFPC or delphi and 64/32 target).

Platforms: Win7/64, Linux Mint Ulyssa/64

Bart

  • Hero Member
  • *****
  • Posts: 4970
    • Bart en Mariska's Webstek
Re: Magic, non referenced variable changes it's value
« Reply #5 on: May 26, 2023, 08:27:14 am »
IIRC then this has already been reported.

Bart

Fibonacci

  • New member
  • *
  • Posts: 7
Re: Magic, non referenced variable changes it's value
« Reply #6 on: May 26, 2023, 08:31:26 am »
I created a new issue on GitLab with some more info, disassemly and asmlists

https://gitlab.com/freepascal.org/fpc/source/-/issues/40291

Bart

  • Hero Member
  • *****
  • Posts: 4970
    • Bart en Mariska's Webstek
Re: Magic, non referenced variable changes it's value
« Reply #7 on: May 26, 2023, 10:53:59 am »
As I thought: it was already reported: https://gitlab.com/freepascal.org/fpc/source/-/issues/39908

Bart

 

TinyPortal © 2005-2018