Lazarus

Free Pascal => General => Topic started by: Fibonacci on September 27, 2024, 12:31:10 pm

Title: Array of Integer as parameter accepts Integers
Post by: Fibonacci on September 27, 2024, 12:31:10 pm
Seems like an Integer can be passed to a procedure that accepts an Array of Integers. Why is that?

Code: Pascal  [Select][+][-]
  1. uses SysUtils;
  2.  
  3. procedure test(a: array of integer);
  4. var
  5.   i: integer;
  6. begin
  7.   writeln('len  = ', length(a), ', size = ', sizeof(a):3);
  8.   for i := 0 to high(a) do writeln(i, ' = ', inttohex(a[i]));
  9. end;
  10.  
  11. begin
  12.   //test(1);           // project1.lpr(14,9) Error: Incompatible type for arg no. 1: Got "ShortInt", expected "{Open} Array Of LongInt"
  13.   test(integer(1));
  14.   //test($ffff);       // project1.lpr(16,13) Error: Incompatible type for arg no. 1: Got "Word", expected "{Open} Array Of LongInt"
  15.   test(integer($ffff));
  16.   test($ffff+1);
  17.   test(123456789);
  18.  
  19.   test([1, $ffff, $ffff+1, 123456789]);
  20.  
  21.   readln;
  22. end.

Quote
len  = 1, size =   4
0 = 00000001
len  = 1, size =   4
0 = 0000FFFF
len  = 1, size =   4
0 = 00010000
len  = 1, size =   4
0 = 075BCD15
len  = 4, size =  16
0 = 00000001
1 = 0000FFFF
2 = 00010000
3 = 075BCD15
Title: Re: Array of Integer as parameter accepts Integers
Post by: MarkMLl on September 27, 2024, 12:41:13 pm
Seems fairly logical to me: you've declared the parameter to accept any number of integers in an array. This might be mode-specific: what compiler mode are you using (and what compiler version etc.)?

MarkMLl
Title: Re: Array of Integer as parameter accepts Integers
Post by: ASerge on September 27, 2024, 01:54:54 pm
Seems like an Integer can be passed to a procedure that accepts an Array of Integers. Why is that?
Yes, this is not reflected in the documentation.
For example from Delphi 7 documentation:
Quote
Within the body of a routine, open array parameters are governed by the following rules.
  • They are always zero-based. The first element is 0, the second element is 1, and so forth. The standard Low and High functions return 0 and Length - 1, respectively. The SizeOf function returns the size of the actual array passed to the routine.
  • They can be accessed by element only. Assignments to an entire open array parameter are not allowed.
  • They can be passed to other procedures and functions only as open array parameters or untyped var parameters. They cannot be passed to SetLength.
  • 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 have bold the last point. FPC extended this action not only for variables, but also for constants, but only those for which the type is set.
Title: Re: Array of Integer as parameter accepts Integers
Post by: Fibonacci on September 27, 2024, 02:15:58 pm
Kudos ASerge, always like your responses
Title: Re: Array of Integer as parameter accepts Integers
Post by: PascalDragon on September 28, 2024, 04:26:15 pm
Seems like an Integer can be passed to a procedure that accepts an Array of Integers. Why is that?

Open array parameters are essentially a pointer to the first element and an additional argument with the high value of the array. It's logical that one can also pass single elements as essentially a single element array. This is compatible to Delphi and works in any mode that supports open array parameters. If it's not documented then someone please file a bug report against the documentation.
Title: Re: Array of Integer as parameter accepts Integers
Post by: marcov on September 28, 2024, 05:06:06 pm
It is not just accepting one element, but more the omission of the [] ?
Title: Re: Array of Integer as parameter accepts Integers
Post by: TRon on September 28, 2024, 05:20:21 pm
@marcov
exactly that.

Because if that would to be desired behaviour then why
Code: Pascal  [Select][+][-]
  1. Foo();
Is considered an error.

Should it not be considered an empty array by that same logic ?
Title: Re: Array of Integer as parameter accepts Integers
Post by: marcov on September 28, 2024, 05:38:28 pm
Delphi Seattle refuses the example code with "constants cannot be used as open array arguments".  For all four of the ones without [].
Title: Re: Array of Integer as parameter accepts Integers
Post by: jamie on September 28, 2024, 06:27:00 pm
Don't see a problem here?

The compiler is going to build an array for the parameter in both cases. The "[..]" only needed to not confuse the compiler between parameter count and element count entries beyond one element for the array.

I believe other languages do the same in this case that have managed arrays.


Title: Re: Array of Integer as parameter accepts Integers
Post by: simone on September 28, 2024, 07:21:39 pm
I had already reported this behavior here:

https://forum.lazarus.freepascal.org/index.php/topic,58489.msg435598.html#msg435598

I reiterate my perplexity, given the strong typing of pascal. A scalar parameter of type integer is not an array of integers with length =1. This behavior is justified only by implementation reasons. But I know I'm in the minority..



Title: Re: Array of Integer as parameter accepts Integers
Post by: TRon on September 28, 2024, 07:24:26 pm
@marcov:
thank you for the verifcation

@jamie:
So in your view there is not an issue with the following ?

Code: Pascal  [Select][+][-]
  1. procedure Foo(a: array of integer);
  2. begin
  3. end;
  4.  
  5. procedure Foo(a: integer);
  6. begin
  7. end;
  8.  

I do see a problem there but perhaps that is just me ?

@simone:
you might perhaps be in the minority but I would call it an abomination as the example clearly shows that you can't rely on the behaviour because as soon as you overload your code behaves differently (and without any warning or indication). imho useless and dangerous behaviour.
Title: Re: Array of Integer as parameter accepts Integers
Post by: simone on September 28, 2024, 08:38:24 pm
Tron, I agree. I'm glad there's at least one authoritative forum member who thinks the same way I do on this point.
Title: Re: Array of Integer as parameter accepts Integers
Post by: 440bx on September 28, 2024, 08:45:33 pm
That Foo example really shows why the compiler should _not_ accept an integer variable as a single element array.  It is ambiguous.

The compiler chooses the Foo with the integer parameter but, there is no indication of any kind that is the choice it makes.

The compiler should require the [] to eliminate the ambiguity its absence creates.  The fact that it doesn't require it should be considered a bug.



@simone,

add 1 (me) to the count of members that agree with you.

Title: Re: Array of Integer as parameter accepts Integers
Post by: jamie on September 28, 2024, 09:09:17 pm
No, I don't see a problem with it, Compiler still generates an array which can be tested in code.

the brackets are only there to enclose multiple entries. either way, an array is created.

I'll step out the spotlight on this one because I would rather the compiler allow reduce syntax as much as possible.

Title: Re: Array of Integer as parameter accepts Integers
Post by: alpine on September 28, 2024, 09:16:13 pm
@simone
Count me also.
Title: Re: Array of Integer as parameter accepts Integers
Post by: VisualLab on September 29, 2024, 12:21:33 am
@simone:
...as the example clearly shows that you can't rely on the behaviour because as soon as you overload your code behaves differently (and without any warning or indication). imho useless and dangerous behaviour.

I agree. I also think this should be fixed.
Title: Re: Array of Integer as parameter accepts Integers
Post by: jamie on September 29, 2024, 01:58:43 am
Creating another incompatibility to Delphi?
 %)


Title: Re: Array of Integer as parameter accepts Integers
Post by: TRon on September 29, 2024, 02:42:28 am
Creating another incompatibility to Delphi?
 %)

I am all fine and dandy with Delphi compatibility...

Delphi Seattle refuses the example code with "constants cannot be used as open array arguments".  For all four of the ones without [].

But please let someone be precise which version of Delphi that should be because that is the one question in over two decades that nobody was able to answer and seem to shift all over the place. The compiler compatibility being one and something as simple as the RTL being another one of them. Shouldn't be a difficult question to answer because Delphi users should be able to run into these incompatibility issues all the time. If not for the one version of Delphi then for the other (because Delphi ain't even compatible with itself over all these years). Once you get into the nitty gritty details then this becomes a serious problem and is one of the reasons that Delphi compatibility means bupkis anymore to me these days.

mode delphi does not make ones code Delphi compatible.
Title: Re: Array of Integer as parameter accepts Integers
Post by: ASerge on September 29, 2024, 09:22:30 am
Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2.  
  3. procedure Proc(const A: array of Integer); overload;
  4. begin
  5.   Writeln('Proc with array');
  6. end;
  7.  
  8. procedure Proc(const A: Int64); overload;
  9. begin
  10.   Writeln('Proc with single');
  11. end;
  12.  
  13. var
  14.   i: Integer = 1;
  15. begin
  16.   Proc(i);
  17.   Readln;
  18. end.
This code outputs "Proc with single" in FPC 64x, but is rejected by the compiler in 32x Delphi7: [Error] Project1.dpr(16): Ambiguous overloaded call to 'Proc'.
Please, test on FPC 32x.
Title: Re: Array of Integer as parameter accepts Integers
Post by: simone on September 29, 2024, 09:23:32 am
Recently I'm a bit surprised when a compiler behavior is justified by the need to maintain compatibility with Delphi. This argument is important in principle, but since I realized that core developers and most of the community are against the acceptance of the most recent features introduced by Delphi (such as the infamous inline variables), then I realized that by now the roads have divided and therefore compatibility is a less and less requested need.
Title: Re: Array of Integer as parameter accepts Integers
Post by: 440bx on September 29, 2024, 09:50:54 am
it's noticeable that compatibility with Delphi isn't a consistent requirement.  Sometimes it is, sometimes it isn't.



@Serge,

I'm pleased you tested that in Delphi.  The ambiguity is obvious and allowing it is an obvious bug (apparently incompatible with Delphi)

Title: Re: Array of Integer as parameter accepts Integers
Post by: Thaddy on September 29, 2024, 12:09:58 pm
Please, test on FPC 32x.
There is not a point in testing it if integer in Delphi has a different meaning.
It is only testable if the fpc compiler mode is also specified. The default mode is fpc mode and the size of an integer = smallint.
https://www.freepascal.org/docs-html/current/ref/refsu4.html#x26-250003.1.1
In DCC32 and DCC64 XE2 and dcc32/d12 the output is Proc with array, in D7 it does not compile at all and in fpc 3.3.1 in delphi mode the output is as you described,  "Proc with single", which seems wrong indeed.
Seems two bugs: one in Delphi7 since the code should compile as in XE2 or higher, and one in fpc where the evaluation order/precedence seems wrong.
Title: Re: Array of Integer as parameter accepts Integers
Post by: PascalDragon on October 01, 2024, 11:16:44 pm
it's noticeable that compatibility with Delphi isn't a consistent requirement.  Sometimes it is, sometimes it isn't.

The point of Delphi compatibility is that Delphi code compiles in FPC with mode Delphi, but NOT that code written in FPC's Delphi mode compiles in Delphi.

(Inline variables - which would be required for Delphi compatiblity - are a special topic, because the majority of the core devs - me included - is against this feature as whole)
Title: Re: Array of Integer as parameter accepts Integers
Post by: Thaddy on October 02, 2024, 11:49:05 am
Delphi compatibility is walking through murky waters anyway as my tests showed.
TinyPortal © 2005-2018