Recent

Author Topic: Open array parameter accepts non-array var  (Read 8803 times)

riwu

  • New Member
  • *
  • Posts: 15
Open array parameter accepts non-array var
« on: January 25, 2017, 02:28:54 pm »
Code: [Select]
procedure f(arr: array of ShortInt);
begin
  while true do  //works
    f(arr[0]);
end;

procedure g(arr: array of ShortInt);
begin
  g(arr[0]);  //compile error
end;
Is this intended? Why does open array parameter accept non-array argument?

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2280
    • havefunsoft.com
Re: Open array parameter accepts non-array var
« Reply #1 on: January 25, 2017, 04:00:41 pm »
Delphi 7 allows the same as well.
Code: Pascal  [Select]
  1. {$APPTYPE CONSOLE}
  2.  
  3. procedure Test(const a: array of integer);
  4. begin
  5.   writeln(length(a));
  6. end;
  7.  
  8.  
  9. var
  10.   v : integer;
  11. begin
  12.   v:=4;
  13.   Test(v);
  14.   readln;
  15.   { TODO -oUser -cConsole Main : Insert code here }
  16. end.
  17.  

Per Delphi's documentation it's allowed
Quote
Instead of an array, you can pass a variable of the open array parameter's base type. It will be treated as an array of length 1.

I can't find mentioning of that in FPC documentation, but I presume FPC support of open arrays was created after Delphi's. Thus the behavior is intentional.
« Last Edit: January 25, 2017, 04:07:26 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Thaddy

  • Hero Member
  • *****
  • Posts: 9164
Re: Open array parameter accepts non-array var
« Reply #2 on: January 25, 2017, 07:54:44 pm »
Highly risky code, calling a procedure from within itself.
also related to equus asinus.

riwu

  • New Member
  • *
  • Posts: 15
Re: Open array parameter accepts non-array var
« Reply #3 on: January 26, 2017, 07:41:47 am »
Highly risky code, calling a procedure from within itself.
I have another routine with the base type of the array as the parameter (overloaded), but i accidentally placed that below instead of above the open array routine, so it ended up as a recursive call, which is how i discovered this peculiar behavior...


Delphi 7 allows the same as well.

I can't find mentioning of that in FPC documentation, but I presume FPC support of open arrays was created after Delphi's. Thus the behavior is intentional.
Doesn't explain why procedure f compiles but not g though.
« Last Edit: January 26, 2017, 07:44:49 am by riwu »

molly

  • Hero Member
  • *****
  • Posts: 2345
Re: Open array parameter accepts non-array var
« Reply #4 on: January 26, 2017, 08:13:34 am »
Doesn't explain why procedure f compiles but not g though.
That is because they both compile fine for me with fpc 3.0. What version of FPC are you using ?

Thaddy

  • Hero Member
  • *****
  • Posts: 9164
Re: Open array parameter accepts non-array var
« Reply #5 on: January 26, 2017, 08:20:17 am »
It also compiles fine with trunk 3.1.1-r35333
also related to equus asinus.

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2280
    • havefunsoft.com
Re: Open array parameter accepts non-array var
« Reply #6 on: January 26, 2017, 02:10:24 pm »
Doesn't explain why procedure f compiles but not g though.
There's an issue in your posts. You're referring to a compile error, but never say what the exact error is.

I also presume that there the code samples you're showing are different to the code that shows the error.

Try to compile this code. What's the error message would be for you?
Code: Pascal  [Select]
  1. procedure f(arr: array of Integer);
  2. begin
  3.   while true do  
  4.     f(arr[0]);
  5. end;
  6.  
  7. procedure g(arr: array of ShortInt);
  8. begin
  9.   g(arr[0]);
  10. end;
  11.  
  12. var
  13.   a : shortint;
  14.   b : integer;
  15. begin
  16.   g(a);
  17.   f(b);
  18. end.
  19.  

I have another routine with the base type of the array as the parameter (overloaded), but i accidentally placed that below instead of above the open array routine, so it ended up as a recursive call, which is how i discovered this peculiar behavior...
Now, I'm trying to guess what the compile error you're seeing.
And it must be "Error: Can't determine which overloaded function to call". Am i right? ;)

something like this:
Code: Pascal  [Select]
  1. {$mode delphi}
  2. procedure f(s: single); overload;
  3. begin
  4.   writeln(s);
  5. end;
  6.  
  7. procedure f(arr: array of Integer); overload;
  8. begin
  9.   while true do  //Error: Can't determine which overloaded function to call
  10.     f(arr[0]);
  11. end;
  12.  
  13. var
  14.   b : integer;
  15. begin
  16.   f(b); //Error: Can't determine which overloaded function to call
  17. end.
  18.  
« Last Edit: January 26, 2017, 02:52:47 pm by skalogryz »
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Nitorami

  • Sr. Member
  • ****
  • Posts: 368
Re: Open array parameter accepts non-array var
« Reply #7 on: January 26, 2017, 03:53:03 pm »
Interesting issue. I have tried this and found that FPC 3.0.0 generates a compile error "Assignments to formal parameters and arrays are not possible", but the error does not appear if the call to f is made from within a while loop. Odd.

{$mode objfpc}
procedure f(arr: array of ShortInt);
begin
  while true do //uncommenting the while makes the difference
    f(arr[0]);
end;

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2280
    • havefunsoft.com
Re: Open array parameter accepts non-array var
« Reply #8 on: January 26, 2017, 04:20:48 pm »
Here's what I'm getting:

Code: Pascal  [Select]
  1. {$mode objfpc}
  2. procedure f(arr: array of ShortInt);
  3. begin
  4. //  while true do  //works
  5.     f(arr[0]);
  6. end;
  7.  
  8. var
  9.   a : shortint;
  10. begin
  11.   f(a);
  12. end.
  13.  

Code: [Select]
fpc.exe test.pas
Free Pascal Compiler version 3.0.0 [2015/11/16] for i386
Copyright (c) 1993-2015 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling test.pas
test.pas(11,6) Warning: Variable "a" does not seem to be initialized
Linking test.exe
11 lines compiled, 0.4 sec, 25344 bytes code, 1268 bytes data
1 warning(s) issued
Patron Cocoa Widgetset development https://www.patreon.com/skalogryz

Handoko

  • Hero Member
  • *****
  • Posts: 3185
  • My goal: build my own game engine using Lazarus
Re: Open array parameter accepts non-array var
« Reply #9 on: January 26, 2017, 04:32:33 pm »
Commenting and removing the comment ("while true do") both make no difference on my Lazarus 1.6.2 FPC 3.0.0 x86_64-linux. Compile success, no error but 1 warning only.

Thaddy

  • Hero Member
  • *****
  • Posts: 9164
Re: Open array parameter accepts non-array var
« Reply #10 on: January 26, 2017, 04:44:45 pm »
The only way it fails in 2.6.4, 3.0.0 and trunk is to compile it with -Sew

What version is used? Either very old, or he uses -Sew.
also related to equus asinus.

Nitorami

  • Sr. Member
  • ****
  • Posts: 368
Re: Open array parameter accepts non-array var
« Reply #11 on: January 26, 2017, 04:51:20 pm »
This is probably an issue with the optimizer. For me, the error only appears in "normal" mode, but not in debug mode. More precisely, it appears when Level 2 optimization is ON.

Thaddy

  • Hero Member
  • *****
  • Posts: 9164
Re: Open array parameter accepts non-array var
« Reply #12 on: January 26, 2017, 05:05:53 pm »
Also not reproducable with trunc. Given any optimization level.
Of course you will get a segmentation fault when you run it, but that is due to the buggy sourcecode
also related to equus asinus.

Handoko

  • Hero Member
  • *****
  • Posts: 3185
  • My goal: build my own game engine using Lazarus
Re: Open array parameter accepts non-array var
« Reply #13 on: January 26, 2017, 05:10:40 pm »
Tested again using optimization level 0 .. level 4, no difference.

But compile will fail if I use -Sew option.

Nitorami

  • Sr. Member
  • ****
  • Posts: 368
Re: Open array parameter accepts non-array var
« Reply #14 on: January 26, 2017, 05:21:52 pm »
This is funny. To me, the problem seems to be exclusively related to optimization Level 2 and above. Have tried a lot of compiler settings but nothing else matters. Windows 7. Will try again on my home PC which is still at XP.

Edit: Exactly the same with XP, FPC 3.0.0. Delphi or objfpc mode don't matter, neither does -Sew, the error only appears at optimisation level 2 and above. I am using the text mode IDE but that should not be the issue.
« Last Edit: January 26, 2017, 05:44:32 pm by Nitorami »