Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2012-04

Open vs dynamic arrays

8 messages · 4 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mark Morgan Lloyd

I know this is an area of some confusion, and the more explanations I read the more I'm confused.

I've got a procedure like this

   procedure ClrDebug(const panels: array of const);
   var     i: integer;
   begin
     for i := 0 to Length(panels) - 1 do
       ClrDebug(panels[i])
   end { ClrDebug } ;
   procedure ClrDebug(panel: integer)...

I want to call it like this

   ClrDebug([DbgKey, DbgCode1, DbgTx]);

Or anything similar. My original declaration used had a type DbgArray= array of integer but that upset the compiler at the call point, the code above throws an exception every time the procedure's called.

What, please, is the correct syntax to use in this sort of case?

FPC 2.6.0 on Linux x86.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Mark Morgan Lloyd
to cobines
cobines wrote 9 lines
ClrDebug(panels[i]) calls itself again and not procedure ClrDebug(panel: integer)... So stack overflow happens. If you need it only for integers then declare it as: procedure ClrDebug(const panels: array of integer)

Thanks. Making sure it couldn't recurse fixes half the problem, reverting to array of integer fixes the other but I'm not sure why that works when it didn't earlier (i.e. before I'd started using array of const).

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

cobines
to Mark Morgan Lloyd

2012/4/22 Mark Morgan Lloyd :

but I'm not sure why that works when it didn't earlier (i.e. before I'd started using array of const).

You said you used
DbgArray= array of integer

then I assume this declaration?
procedure ClrDebug(const panels: DbgArray);

If so the parameter is a dynamic array not open array and you cannot call it with constant array:

var
  arr: DbgArray;
begin
 ClrDebug([DbgKey, DbgCode1, DbgTx]); //Won't work
 SetLength(arr, ...);
 arr[0] := ...
 ...
 ClrDebug(arr);// This works
end;
This on the other hand is an open array parameter:
procedure ClrDebug(const panels: array of integer);
cobines

Reply by email

Mark Morgan Lloyd
to cobines
cobines wrote 26 lines
2012/4/22 Mark Morgan Lloyd : > but I'm not sure why that works when it > didn't earlier (i.e. before I'd started using array of const). You said you used DbgArray= array of integer then I assume this declaration? procedure ClrDebug(const panels: DbgArray); If so the parameter is a dynamic array not open array and you cannot call it with constant array: var arr: DbgArray; begin ClrDebug([DbgKey, DbgCode1, DbgTx]); //Won't work SetLength(arr, ...); arr[0] := ... ... ClrDebug(arr);// This works end; This on the other hand is an open array parameter: procedure ClrDebug(const panels: array of integer);

Thanks, succinct. So if I understand this correctly it's one of the very rare cases where one has to write out the type of a parameter in full, rather than using an earlier declaration.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Michael Van Canneyt
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 31 lines
cobines wrote: > 2012/4/22 Mark Morgan Lloyd : >> but I'm not sure why that works when it >> didn't earlier (i.e. before I'd started using array of const). > > You said you used > DbgArray= array of integer > > then I assume this declaration? > procedure ClrDebug(const panels: DbgArray); > > If so the parameter is a dynamic array not open array and you cannot > call it with constant array: > > var > arr: DbgArray; > begin > ClrDebug([DbgKey, DbgCode1, DbgTx]); //Won't work > SetLength(arr, ...); > arr[0] := ... > ... > ClrDebug(arr);// This works > end; > > > This on the other hand is an open array parameter: > procedure ClrDebug(const panels: array of integer); Thanks, succinct. So if I understand this correctly it's one of the very rare cases where one has to write out the type of a parameter in full, rather than using an earlier declaration.

It results in different declarations.

type
   DbgArray = array of integer;
procedure ClrDebug(const panels: DbgArray);

Defines a procedure that accepts a dynamic array of type DbgArray. You cannot have "constant dynamic arrays", as they are managed on the heap and reference counted.

On the other hand

procedure ClrDebug(const panels: array of integer);

Defines a procedure that accepts an open array: an array of integers, but without length. It accepts types as

type
   SmallArray = array[1..100] of integer;
   LargeArray = array[1..10000] of integer;

And a constant array (and a dynamic array, if I'm correct) as well.

I'll see if I can add something about it in the docs.

Michael.

Reply by email

Mark Morgan Lloyd
to Michael Van Canneyt
Michael Van Canneyt wrote 59 lines
On Sun, 22 Apr 2012, Mark Morgan Lloyd wrote: > cobines wrote: >> 2012/4/22 Mark Morgan Lloyd : >>> but I'm not sure why that works when it >>> didn't earlier (i.e. before I'd started using array of const). >> >> You said you used >> DbgArray= array of integer >> >> then I assume this declaration? >> procedure ClrDebug(const panels: DbgArray); >> >> If so the parameter is a dynamic array not open array and you cannot >> call it with constant array: >> >> var >> arr: DbgArray; >> begin >> ClrDebug([DbgKey, DbgCode1, DbgTx]); //Won't work >> SetLength(arr, ...); >> arr[0] := ... >> ... >> ClrDebug(arr);// This works >> end; >> >> >> This on the other hand is an open array parameter: >> procedure ClrDebug(const panels: array of integer); > > Thanks, succinct. So if I understand this correctly it's one of the > very rare cases where one has to write out the type of a parameter in > full, rather than using an earlier declaration. It results in different declarations. type DbgArray = array of integer; procedure ClrDebug(const panels: DbgArray); Defines a procedure that accepts a dynamic array of type DbgArray. You cannot have "constant dynamic arrays", as they are managed on the heap and reference counted. On the other hand procedure ClrDebug(const panels: array of integer); Defines a procedure that accepts an open array: an array of integers, but without length. It accepts types as type SmallArray = array[1..100] of integer; LargeArray = array[1..10000] of integer; And a constant array (and a dynamic array, if I'm correct) as well. I'll see if I can add something about it in the docs.

Hopefully Google will pick this up as a guide for the perplexed :-)

So if I understand things correctly, the important point here is that while it is good practice to do e.g.

type dbgArray3= array[0..2] of integer;
procedure clrDebug3(da: dbgArray3);

rather than

procedure clrDebug3(da: array[0..2] of integer);

you quite simply can't do that when there isn't an explicit index range since your attempt to define an open array is interpreted as a dynamic array.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Jonas Maebe
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote
you quite simply can't do that when there isn't an explicit index range since your attempt to define an open array is interpreted as a dynamic array.

Yes. The reason is that you can't declare variables whose type is "open array". In fact, a dynamic array is pretty much what you get when you implement "open array variables". That's probably what inspired Borland to go down this route...

Jonas

Reply by email