21

in Delphi the procedure write can handle:

write(TF,st1)

and

write(TF,st1,st2,st3,st4);

I want to declare a procedure that can also do that, what is the syntax?

and the option of:

write(TF,[st1,st2,st3])

is less desirable, though I know how to do that.

the main purpose was to pass ShortStrings into function, that would make a read call from file, and would read at the length of the shortString as defined. however after passing it as variant or in open array the shortString loses its "size" and become 255, which making this pass unusable, for me. but the answer is still got if you want to pass open array.

fejese
  • 4,601
  • 4
  • 29
  • 36
none
  • 4,669
  • 14
  • 62
  • 102
  • Really? You couldn't look this up yourself? [How to create functions that can accept variable number of parameters such as Format().](http://www.chami.com/tips/delphi/112696D.html) – Roman Jul 24 '11 at 13:39
  • 1
    Eeh... `inc` doesn't support a variable number of arguments. – Andreas Rejbrand Jul 24 '11 at 13:41
  • @Andreas Well, it does - it can be called with one or two arguments: `Inc(x);` or `Inc(x, y);` But not with unlimited number of arguments like the OP wrote... – ain Jul 24 '11 at 13:43
  • No, `Inc` can't handle unlimited number of parameters – kludg Jul 24 '11 at 13:43
  • i changed the question from inc to write, as write DO support this option. – none Jul 24 '11 at 13:45
  • 1
    @ROMANARMY that does answer the question : how to create a procedure write(TF,[st1,st2,st3]); which was no the question. – none Jul 24 '11 at 13:49
  • Hey there none. How do you plan to HANDLE the infinite parameters on the other side? Delphi lacks both the C calling convention, and the primitives to handle variadics (va_start, va_arg). – Warren P Jul 25 '11 at 19:16
  • @Warren P , with a for low to high. – none Jul 27 '11 at 10:22

3 Answers3

31

Just to complement Cosmin's answer: if the list of parameters are of different types, you could use an variant open array parameter (also know as "array of const"). More on Delphi documentation.

Example (from documentation):

function MakeStr(const Args: array of const): string;
var
  I: Integer;
begin
  Result := '';
  for I := 0 to High(Args) do
     with Args[I] do
        case VType of
            vtInteger:  Result := Result + IntToStr(VInteger);
            vtBoolean:  Result := Result + BoolToStr(VBoolean);
            vtChar:     Result := Result + VChar;
            vtExtended: Result := Result + FloatToStr(VExtended^);
            vtString:   Result := Result + VString^;
            vtPChar:    Result := Result + VPChar;
            vtObject:   Result := Result + VObject.ClassName;
            vtClass:    Result := Result + VClass.ClassName;
            vtAnsiString:  Result := Result + string(VAnsiString);
            vtCurrency:    Result := Result + CurrToStr(VCurrency^);
            vtVariant:     Result := Result + string(VVariant^);
            vtInt64:       Result := Result + IntToStr(VInt64^);
  end;
end;
Fabricio Araujo
  • 3,810
  • 3
  • 28
  • 43
29

First of all Inc and Write are bad examples because they both get special treatment from the compiler. You can't write a function that behaves exactly like those two do yourself. There are alternatives you should investigate.

Take a look at overloads

You can create multiple versions of your method using varying number of parameters, and varying types. Something like this:

procedure MyInc(var i:Integer); overload;
procedyre MyInc(var i:Integer; const N:Integer); overload;
procedure MyInc(var i:Integer; const N1, N2: Integer); overload;
procedure MyInc(var i:Integer; const N1, N2, N3: Integer):overload;

This is feasible if the required number of overloads is not that large. The compiler would probably handle lots of overloads easily, but you'd probably not want to write them. When the number of overloads becomes a problem you can switch to arrays:

Using Open Arrays as parameters

A function can take a parameter of type array of YourType, and when you call that function you can pass as many parameters as you might need:

procedure MyInc(var i:Integer; Vals: array of Integer);

And then use it like this:

MyInc(i, []); // no parameters
MyInc(i, [1]);
MyInc(i, [1, 34, 43, 12]);
Community
  • 1
  • 1
Cosmin Prund
  • 25,498
  • 2
  • 60
  • 104
13

For ilustrative purposes only:

Delphi supports a way of writing "real" variable arguments functions, but it is really cumbersome and intended for use mainly for declaring external C functions with variable arguments like printf, as it involves playing some low-level dirty tricks for accessing the arguments in the stack.

It involves using cdecl and varargs modifiers:

procedure MyWrite_; cdecl;
begin
  ... some magic here ...
end;

var
  MyWrite: procedure; cdecl varargs = MyWrite_;

begin
  MyWrite(1);
  MyWrite(1, 2);
  MyWrite(1, 2, 3);
end;

More detailed explanation can be found in the answer from Barry Kelly to How can a function with 'varargs' retrieve the contents of the stack?

Community
  • 1
  • 1
JRL
  • 3,363
  • 24
  • 36