In Object Pascal or Delphi mode, Free Pascal supports the Array of Const construction to pass parameters to a subroutine.
This is a special case of the Open array construction, where it is allowed to pass any expression in an array to a function or procedure.
In the procedure, passed the arguments can be examined using a special record:
Type
PVarRec = ^TVarRec; TVarRec = record case VType : Longint of vtInteger : (VInteger: Longint); vtBoolean : (VBoolean: Boolean); vtChar : (VChar: Char); vtExtended : (VExtended: PExtended); vtString : (VString: PShortString); vtPointer : (VPointer: Pointer); vtPChar : (VPChar: PChar); vtObject : (VObject: TObject); vtClass : (VClass: TClass); vtAnsiString : (VAnsiString: Pointer); vtWideString : (VWideString: Pointer); vtInt64 : (VInt64: PInt64); end; |
Inside the procedure body, the array of const is equivalent to an open array of TVarRec:
Procedure Testit (Args: Array of const);
Var I : longint; begin If High(Args)<0 then begin Writeln ('No aguments'); exit; end; Writeln ('Got ',High(Args)+1,' arguments :'); For i:=0 to High(Args) do begin write ('Argument ',i,' has type '); case Args[i].vtype of vtinteger : Writeln ('Integer, Value :',args[i].vinteger); vtboolean : Writeln ('Boolean, Value :',args[i].vboolean); vtchar : Writeln ('Char, value : ',args[i].vchar); vtextended : Writeln ('Extended, value : ',args[i].VExtended^); vtString : Writeln ('ShortString, value :',args[i].VString^); vtPointer : Writeln ('Pointer, value : ',Longint(Args[i].VPointer)); vtPChar : Writeln ('PCHar, value : ',Args[i].VPChar); vtObject : Writeln ('Object, name : ',Args[i].VObject.Classname); vtClass : Writeln ('Class reference, name :',Args[i].VClass.Classname); vtAnsiString : Writeln ('AnsiString, value :',AnsiString(Args[I].VAnsiStr else Writeln ('(Unknown) : ',args[i].vtype); end; end; end; |
In code, it is possible to pass an arbitrary array of elements to this procedure:
S:='Ansistring 1';
T:='AnsiString 2'; Testit ([]); Testit ([1,2]); Testit (['A','B']); Testit ([TRUE,FALSE,TRUE]); Testit (['String','Another string']); Testit ([S,T]) ; Testit ([P1,P2]); Testit ([@testit,Nil]); Testit ([ObjA,ObjB]); Testit ([1.234,1.234]); TestIt ([AClass]); |
If the procedure is declared with the cdecl modi er, then the compiler will pass the array as a C compiler would pass it. This, in e ect, emulates the C construct of a variable number of arguments, as the following example will show:
program testaocc;
{$mode objfpc} Const P : Pchar = 'example'; Fmt : PChar = 'This %s uses printf to print numbers (%d) and strings.'#10; // Declaration of standard C function printf: procedure printf (fm : pchar; args : array of const);cdecl; external 'c'; begin printf(Fmt,[P,123]); end. |
Remark that this is not true for Delphi, so code relying on this feature will not be portable.