Q:  How do I use "array of const"?

A: An array of const is in fact an open array of TVarRec (a predeclared Delphi type you can look up in the online help). So the following is the general battle plan:

procedure AddStuff( Const A: Array of Const );
Var i: Integer;
Begin
  For i:= Low(A) to High(A) Do
  With A[i] Do
    Case VType of
    vtExtended: Begin
       { add real number, all real formats are converted to extended automatically }
      End;
    vtInteger: Begin
       { add integer number, all integer formats are converted to LongInt automatically }
      End;
    vtObject: Begin
        If VObject Is DArray Then
          With DArray( VObject ) Do Begin
            { add array of doubles }
          End
        Else If VObject Is IArray Then
          With IArray( VObject ) Do Begin
            { add array of integers }
          End;
      End;
    End; { Case }
End; { AddStuff }
 

For further information see "open arrays" in the on-line help.

Here is a bit more from Steve:

An "array of const" is an array of values passed as const. Internally, these are represented by TVarRec structures. The brackets are simply to delimit the array. Arrays of const give you the ability to send a variable number of parameters to a routine in a type-safe manner. Here's an example:

 type
   TVarRec = record
     Data: record case Integer of
       0: (L: LongInt);
       1: (B: Boolean);
       2: (C: Char);
       3: (E: ^Extended);
       4: (S: ^String);
       5: (P: Pointer);
       6: (X: PChar);
       7: (O: TObject);
       end;
     Tag: Byte;
     Stuff: array[0..2] of Byte;
     end;

 function PtrToStr(P: Pointer): String;
 const
   HexChar: array[0..15] of Char = '0123456789ABCDEF';

   function HexByte(B: Byte): String;
   begin
   Result := HexChar[B shr 4] + HexChar[B and 15];
   end;

   function HexWord(W: Word): String;
   begin
   Result := HexByte(Hi(W)) + HexByte(Lo(W));
   end;

 begin
 Result := HexWord(HiWord(LongInt(P))) + ':' + HexWord(LoWord(LongInt(P)));
 end;

 procedure Display(X: array of const);
 var
   I: Integer;
 begin
 for I := 0 to High(X) do with TVarRec(X[I]), Data do
   begin
   case Tag of
     0: ShowMessage('Integer: ' + IntToStr(L));
     1: if B then ShowMessage('Boolean: True')
       else ShowMessage('Boolean: False');
     2: ShowMessage('Char: ' + C);
     3: ShowMessage('Float: ' + FloatToStr(E^));
     4: ShowMessage('String: ' + S^);
     5: ShowMessage('Pointer: ' + PtrToStr(P));
     6: ShowMessage('PChar: ' + StrPas(X));
     7: ShowMessage('Object: ' + O.ClassName);
     end;
   end;
 end;

 procedure TForm1.Button1Click(Sender: TObject);
 var
   P: array[0..5] of Char;

 begin
 P := 'Hello'#0;
 Display([-12345678, True, 'A', 1.2345, 'ABC', Ptr($1234, $5678), P,
   Form1]);
 end;

Here is some more on this subject:

A typical candidate for an Array of Const or open array parameter. An Array of Const can take a mix of different types, an open array only an array of items all of the same base class. Inside the function you treat the array of
const parameter as an open array of TVarRec. Dealing with all the possible parameter types can be quite complicated, however.

function Max(elem: array of const): TVarRec;
var
  i: Word;
  b: boolean;
begin
{ Note that open array index range is always zero-based. }
  Result := elem[0];
  for i := 1 to High(elem) do begin
    case Result.VType of
    vtInteger:
      try
        case elem[i].VType of
          vtInteger:   b := (elem[i].VInteger > Result.VInteger);
          vtChar:      b := (longint(elem[i].VChar) > Result.VInteger);
          vtExtended:  b := (elem[i].VExtended^ > Result.VInteger);
          vtString:    b := (StrToInt(elem[i].VString^) > Result.VInteger);
          vtPChar:     b := (StrToInt(StrPas(elem[i].VPChar)) > Result.VInteger);
        else           b := FALSE;
        end; {case}
      except
        b := FALSE;
      end;
    vtChar:
      try
        case elem[i].VType of
          vtInteger:   b := (char(elem[i].VInteger) > Result.VChar);
          vtChar:      b := (elem[i].VChar > Result.VChar);
          vtExtended:  b := (elem[i].VExtended^ > longint(Result.VChar));
          vtString:    b := (elem[i].VString^ > Result.VChar);
          vtPChar:     b := (elem[i].VPChar[0] > Result.VChar);
        else           b := FALSE;
        end;
      except
        b := FALSE;
      end;
    vtExtended:
      try
        case elem[i].VType of
          vtInteger:   b := (elem[i].VInteger > Result.VExtended^);
          vtChar:      b := (longint(elem[i].VChar) > Result.VExtended^);
          vtExtended:  b := (elem[i].VExtended^ > Result.VExtended^);
          vtString:    b := (StrToFloat(elem[i].VString^) > Result.VExtended^);
          vtPChar:     b := (StrToFloat(StrPas(elem[i].VPChar)) > Result.VExtended^);
        else           b := FALSE;
        end; {case}
      except
        b := FALSE;
      end;
    vtString:
      try
        case elem[i].VType of
          vtInteger:   b := (elem[i].VInteger > StrToInt(Result.VString^));
          vtChar:      b := (elem[i].VChar > Result.VString^);
          vtExtended:  b := (elem[i].VExtended^ > StrToFloat(Result.VString^));
          vtString:    b := (elem[i].VString^ > Result.VString^);
          vtPChar:     b := (StrPas(elem[i].VPChar) > Result.VString^);
        else           b := FALSE;
        end;
      except
        b := FALSE;
      end;
    vtPChar:
      try
        case elem[i].VType of
          vtInteger:   b := (elem[i].VInteger > StrToInt(StrPas(Result.VPChar)));
          vtChar:      b := (elem[i].VChar > Result.VPChar[0]);
          vtExtended:  b := (elem[i].VExtended^ > StrToFloat(StrPas(Result.VPChar)));
          vtString:    b := (elem[i].VString^ > StrPas(Result.VPChar));
          vtPChar:     b := (StrComp(elem[i].VPChar, Result.VPChar) > 0);
        else           b := FALSE;
        end;
      except
        b := FALSE;
      end;
    end; {case}
    if (b) then Result := elem[i];
  end; {for}
end; { Max }