> The actual names of the parameter passing conventions are Value and
> Reference.
>
> Using Var or Const causes a pass by reference otherwise parameters are
> *always*
> pass by value.
>
> The Catch?  Delphi is lying to you...
>
> procedure A(Obj :TObject);
> begin
>    Obj.Free;
>    Obj := nil;
> end;
>
> procedure B(var Obj :TObject);
> begin
>   Obj.Free;
>   Obj. := nil;
> end;
>
> var
>     X :TStringList;
> begin
>     X := TStringList.Create;
>     A(X);
>     // X is not nil but the StringList doesn't exist anymore;
>     X := TStringList.Create;
>     B(X);
>     // X is nil and the StringList doesn't exist anymore;
> end;

So the point is?

In procedure A, you are passing a reference by value, and in procedure B,
you are passing a reference by reference (ie. pointer to pointer).  Where is
it that Delphi lies?  Bear in mind that all objects in Delphi are references
(ie pointers).

[Snip...]

> > That doesn't seem to apply in Delphi 3 as instances pass as value
> parameters
> > fine (the compiler presumably still passes a reference
> rather than the
> > object itself, though)
>
> The passing process has always been this way since D1... Note
> that Records,
> strings
> and arrays should always be passed as const or var so that
> delphi does not
> 'copy' the
> data using unnecessary memory.

This is not necessarily true.  In D2 and above, passing a string (which by
default is an AnsiString) by value only passes the string REFERENCE by
value.  This means only the reference (pointer) is copied.  The data is not.
If you then modified the string in the procedure, the copy on write
mechanism in Delphi will then create a new instance.

var
  p: Pointer;
  a: string;

  procedure foo (b: string);
  begin
    // Set p to point to data referenced by b
    // (but is the same data as a - ie., no copying)
    p := PChar(b);
    // Changing the first character of the data that
    //  p points to will change BOTH a and b.
    PChar(p)^ := 'q';
    // Set b to refer to another set of string data
    // (but a is unaffected because b is a SEPARATE reference)
    b := 'def';
    // Set p to point to data referenced by b ('def')
    //  (which now is different from a)
    p := PChar(b);
  end;


begin
  a := '';
  p := PChar(a);  // p = Nil
  a := 'abc';
  // set p to point to the data referenced by a ('abc')
  p := PChar(a);
  // formal parameter b is now a copy of a (passing by value)
  foo (a);
  // p is now pointing to limbo, because after the call to
  // foo(), b no longer exists.
  // a now references the string 'qbc'.
end.


Regards,
Dennis.

---------------------------------------------------------------------------
    New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
                  Website: http://www.delphi.org.nz

Reply via email to