2

I have a procedure in Delphi which currently looks like this:

Procedure Time.TimeDB(algorithm: string; Encode, Decode: InputFunction; N, R: Int);
VAR
    i : LongInt;
    Errors : Array[N] of LongInt;
BEGIN

for i := 0 to N-1 do
  Errors[i] := 0;

END;

I'm given the error that N, as passed to the definition of Errors, is an undeclared identifier, despite declaring it in the procedure definition. N is recognized in the BEGIN-END section, though. Any ideas what's causing this and how I can otherwise declare a variable-length array in the VAR section?

Gabriel
  • 20,797
  • 27
  • 159
  • 293
user2163043
  • 361
  • 1
  • 3
  • 14
  • You need to use SetLength. Take a look at this small program: https://github.com/GodModeUser/DemoCode/tree/main/DataTypes%20-%20SizeOf – Gabriel Nov 09 '22 at 16:19

2 Answers2

11

You write array of Int to declare a dynamic array of Ints:

procedure Time.TimeDB(algorithm: string; Encode, Decode: InputFunction; N, R: Int);
var
  i: int;
  errors: array of Int;
begin

  SetLength(errors, N);
  for i := 0 to N - 1 do
    Errors[i] := 0;

end;

Also notice that if an array has N elements, then they are indexed 0, 1, ..., N - 1. There is no element indexed N.

(Also, are you sure you don't mean integer when you write Int?)


The construct array[M..N] of Int is called a static array. In this case, M and N must be constants, like array[0..15] of TColor. You also got the static array declaration array[TMyType] of TMySecondType where the index will be of type TMyType, as in array[byte] of TColor or array[TFontStyle] of cardinal.

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • Woops sorry I defined Int as LongInt earlier in the code but forgot to copy it here with the rest, and the N-1 thing was a slip, thanks for pointing it out. I've edited the question accordingly. Thanks for the help on this - are static arrays made at compile time then, hence 'N' not being an acceptable length for them? – user2163043 Aug 12 '13 at 08:27
  • @user2163043: True. `N` is simply not a constant, so `errors[0..N-1]` will never work. – Andreas Rejbrand Aug 12 '13 at 10:34
1

In your code your initializing your Errors Array to zero...Note with SetLength you don't need to do this...just set the Array to 0 and then set it to the length you want, and then just assign the values you need.

procedure WorkArrays(var aWorking: array of integer);
begin
  if High(aWorking) >= 0 then
    aWorking[0] := 1;
  if High(aWorking) >= 3 then
    aWorking[3] := 5;
end;

procedure WorkArrays2(var aWorking: array of integer);
begin
  if High(aWorking) >= 1 then
    aWorking[1] := 4;
  if High(aWorking) >= 9 then
    aWorking[9] := 7;
end;

procedure WorkArrays3(var aWorking: TIntArray);
begin
  SetLength(aWorking, 4);
  aWorking[0] := 1;
  aWorking[3] := 5;
end;

procedure WorkArrays4(var aWorking: TIntArray);
begin
  SetLength(aWorking, 10);
  aWorking[1] := 4;
  aWorking[9] := 7;
end;

procedure TForm58.ShowArrays(aWorking: array of integer);
var
  a_Index: integer;
begin
  for a_Index := Low(aWorking) to High(aWorking) do
    Memo1.Lines.Add(IntToStr(aWorking[a_Index]));
end;

procedure TForm58.ShowArrays2(aWorking: TIntArray);
var
  a_Index: integer;
begin
  for a_Index := Low(aWorking) to High(aWorking) do
    Memo1.Lines.Add(IntToStr(aWorking[a_Index]));
end;

procedure TForm58.Button1Click(Sender: TObject);
var
  a_MyArray: array of integer;
  a_MyArray1: TIntArray;
begin
  SetLength(a_MyArray, 3);//note this is a Zero based Array...0 to 2
  WorkArrays(a_MyArray);//note aWorking[3] will not show...because High is 2...
  ShowArrays(a_MyArray);
  SetLength(a_MyArray, 0);
  SetLength(a_MyArray, 10);//note this is a Zero based Array...0 to 9
  WorkArrays2(a_MyArray);
  ShowArrays(a_MyArray);
  WorkArrays3(a_MyArray1);
  ShowArrays2(a_MyArray1);
  WorkArrays4(a_MyArray1);
  ShowArrays2(a_MyArray1);
end;

end.

House of Dexter
  • 386
  • 1
  • 7