Recent

Author Topic: Compiler ignores function call in mode objfpc  (Read 348 times)

Nitorami

  • Sr. Member
  • ****
  • Posts: 440
Compiler ignores function call in mode objfpc
« on: March 17, 2023, 06:37:21 pm »
I experience a strange issue here with a small unit I made for an MWC random generator. The generator is an advanced record and provides two overloaded functions whose purpose should be obvious:

Code: Pascal  [Select][+][-]
  1. rand32i: dword; overload;
  2. rand32i (range: dword): dword; overload;

The latter should return a random value in a range, and it calls the first version:

Code: Pascal  [Select][+][-]
  1. function TGenMWC.rand32i (const range: dword): dword;
  2. begin
  3.   result := rand32i mod range; //adding brackets rand32i() solves the issue
  4. end;

This works in mode delphi, but in mode objfpc the compiler complains that the function result might not be initialised; and in fact it seems that rand32i is never called, instead, the function always returns the same number, some garbage it found on the stack apparently. The compiler seems to confuse a function call with a variable; changing rand32i to rand32i() solves the issue.

Interestingly, when moving the entire code into a single program, the problem also disappears.

Tested with FPC3.2.0 and 3.2.3 of 2023/03/05, i386-win32.

Can someone please test before I file a bug report. Simply compile in mode objfpc and run. The random numbers generated by R.rand32i (1000) should not all be the same.

Thaddy

  • Hero Member
  • *****
  • Posts: 12933
Re: Compiler ignores function call in mode objfpc
« Reply #1 on: March 17, 2023, 06:48:16 pm »
It is probably not a bug, but can you test against my Marsaglia class from the wiki? That one is certified to be correct.
https://wiki.freepascal.org/Marsaglia%27s_pseudo_random_number_generators

The same seed should give the same result...

It is also pretty well documented....
« Last Edit: March 17, 2023, 07:05:34 pm by Thaddy »
In memory of Gordon Moore  (January 3, 1929 – March 24, 2023) Just double the heaven every two years from now.

Blaazen

  • Hero Member
  • *****
  • Posts: 3160
  • POKE 54296,15
    • Eye-Candy Controls
Re: Compiler ignores function call in mode objfpc
« Reply #2 on: March 17, 2023, 07:06:41 pm »
I can confirm in 3.3.1. It looks like a bug.
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/

Thaddy

  • Hero Member
  • *****
  • Posts: 12933
Re: Compiler ignores function call in mode objfpc
« Reply #3 on: March 17, 2023, 07:15:11 pm »
I can confirm in 3.3.1. It looks like a bug.
Where? That code is a mess. Plz test against a reference. (I gave you one)
Note that FreePascal does not always play nice with signed vs unsigned and Boolean operations.

The MWC is quite easy, though, so maybe a cast or two more? Or copy my code...
« Last Edit: March 17, 2023, 07:17:54 pm by Thaddy »
In memory of Gordon Moore  (January 3, 1929 – March 24, 2023) Just double the heaven every two years from now.

Blaazen

  • Hero Member
  • *****
  • Posts: 3160
  • POKE 54296,15
    • Eye-Candy Controls
Re: Compiler ignores function call in mode objfpc
« Reply #4 on: March 17, 2023, 07:25:41 pm »
Code: Pascal  [Select][+][-]
  1. type  TGenMWC = record
  2.         private
  3.           si, ri: dword;
  4.           state:  array [0..1] of dword;
  5.           class operator Initialize (var R: TGenMWC);
  6.           procedure init_seeded (x: dword);
  7.         public
  8.           function  rand32i: dword;  overload;
  9.           function  rand32i (const range: dword): dword; overload;
  10.           procedure randomize;
  11.       end;
and
Code: Pascal  [Select][+][-]
  1. function TGenMWC.rand32i: dword;
  2. var t: qword;
  3. begin
  4.   si := (si+1) and 1;
  5.   t :=  state[si]*qword (4294967253) + ri;
  6.   state[si] := lo(t);
  7.   ri     := hi(t);
  8.   result := lo(t);
  9. end;
  10.  
  11. function TGenMWC.rand32i (const range: dword): dword;
  12. begin
  13.   result := rand32i() mod range;
  14. end;

The second method should call the first. It does in Delphi mode OR when you add braces:   result := rand32i() mod range;

In ObjFpc without braces it does not work:   result := rand32i mod range;
It's a bug, the function are correctly declared and overloaed, it should work.
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/

Thaddy

  • Hero Member
  • *****
  • Posts: 12933
Re: Compiler ignores function call in mode objfpc
« Reply #5 on: March 17, 2023, 07:47:52 pm »
Hm. that seems like a bug, but the algorithm is also not implemented correctly.
I will come back with a detailed explanation. For now: if it is urgent, copy my code.
In memory of Gordon Moore  (January 3, 1929 – March 24, 2023) Just double the heaven every two years from now.

Nitorami

  • Sr. Member
  • ****
  • Posts: 440
Re: Compiler ignores function call in mode objfpc
« Reply #6 on: March 18, 2023, 06:41:45 pm »
Thaddy, i know your library, but the issue is about what I thought is a bug more than about the random generator code as such.

I filed a bug report but it is not a bug: The issue is that the compiler accepts the function name as result and therefore believes that rand32i is "result". A horrible design decision from from Turbo pascal days I had long fogotten about.

Thaddy

  • Hero Member
  • *****
  • Posts: 12933
Re: Compiler ignores function call in mode objfpc
« Reply #7 on: March 18, 2023, 06:49:18 pm »
The issue is that the compiler accepts the function name as result
Which is also known as Pascal.
"Result" was introduced much later.
In memory of Gordon Moore  (January 3, 1929 – March 24, 2023) Just double the heaven every two years from now.

 

TinyPortal © 2005-2018