Board index » delphi » Parameter passing

Parameter passing

I am just starting to learn pascal and I was wondering if someone could
explain how parameter passing works, in plain english terms.

Your help would be much appreciated.

Thanks

 

Re:Parameter passing


Quote
> I am just starting to learn pascal and I was wondering if someone could
> explain how parameter passing works, in plain english terms.

   In Pascal, there are two classes of parameters: Value and Reference.  
Both classes are passed to the procedure/function via pointers (the
subprogram receives the _address_ of something, not its value), and the
key difference is what the pointer points to:
        - Value parameters pass the address of a _copy_ of the data.
        - Reference parameters pass the address of the _data_.
   So, in one case (the Reference parameter), the subprogram is given the
address of the program's data, and any change to it by the subprogram
alters the real data - sometimes a risky thing to let a subprogram do.  
If _value_ parameters are used, the subprogram can change the data all it
wants, but the original program data is protected (unaltered), because
the subprogram is working with a _copy_ of the program's original
data...no harm possible.
   Reference parameters always have the "var" clause added in the
subprogram definition; values parameters don't.  For example:

procedure Ref_Param (var X : integer);
procedure Val_Param (X : integer);

   Both subprograms will receive a passed parameter (type integer) which
they know as X, and both can use the X data any way they want (read it,
assign new value to it, display it, etc.), but any changes made to it are
effective only in the Ref_Param routine - because only that subprogram
has the address of the real data (the other has the address of a copy of
the data).  Pascal generates runtime code for all subprogram calls to set
up these addresses and actually copies the program's data (to a location
on the Stack) if a Value parameter is being passed.  Thus, while Value
parameters are safer to use, they are somewhat slower to have in
execution and run a risk of using a lot of Stack when used.  (However,
most academics favor Value parameters, because their use "protects"
program data in subprograms where changing the data shouldn't be
allowed...)
   Note that all this is controlled through the subprogram's
_declaration_, and the calls to the subprograms do nothing special.  That
is, the calls to both Ref_Param and Val_Param will look the same:
  Val_Param (Y);
  Ref_Param (Y);
but only Ref_Param can actually affect the value of Y when the call is
made (Val_Param may alter what it's passed, but it's working with a copy
of Y, not Y itself).

Re:Parameter passing


In article <MPG.f51efa7e2b90dd0989...@news.primenet.com>,

Quote
Mike Copeland <mrc...@primenet.com> wrote:
>> I am just starting to learn pascal and I was wondering if someone could
>> explain how parameter passing works, in plain english terms.

>   In Pascal, there are two classes of parameters: Value and Reference.  
>Both classes are passed to the procedure/function via pointers (the
>subprogram receives the _address_ of something, not its value), and the
>key difference is what the pointer points to:
>    - Value parameters pass the address of a _copy_ of the data.
>    - Reference parameters pass the address of the _data_.

Incorrect. Value parameters are not passed as pointers. The actual data
is passed, not any address. (In case of complex parameters (like arrays)
technically a pointer to the actual data is passed and then the
initialization part of the procedure copies the data to a local variable
but in practice this is mostly equivalent to passing the actual data)

To illustrate the difference in simple parameters, lets have some code:

procedure Value(x:word);
begin
  x:=1;
End;

procedure Variable(x:word);
begin
  x:=1;
End;

var z:word;

begin
  value(z);
  variable(z);
End.

Now lets see the code that is produced:

Lets first view the calls:

PROGRAM.14:  value(z);
  cs:0023 FF365000       push   word ptr [PROGRAM.Z]
  cs:0027 E8D6FF         call   PROGRAM.VALUE
PROGRAM.15:  variable(z);
  cs:002A BF5000         mov    di,0050
  cs:002D 1E             push   ds
  cs:002E 57             push   di
  cs:002F E8DAFF         call   PROGRAM.VARIABLE

See, how in case of value parameter the actual value of the variable is
pushed on the stack. In case of variable parameter the address (DS:50h)
of the variable is pushed.

Now lets see the actual code:

First for the value version:

PROGRAM.VALUE: begin
  cs:000C 55             push   bp
  cs:0001 89E5           mov    bp,sp
PROGRAM.3:  x:=1;
  cs:0003 C746040100     mov    word ptr [bp+04],0001
PROGRAM.4: End;
  cs:0008 C9             leave
  cs:0009 C20200         ret    0002

See, how this only modifies the parameter on the stack. The ret removes
that parameter so there is no permanent effect.

Then the variable parameter version:

PROGRAM.VARIABLE: begin
  cs:000C 55             push   bp
  cs:000D 89E5           mov    bp,sp
PROGRAM.8:  x:=1;
  cs:000F C47E04         les    di,[bp+04]
  cs:0012 26C7050100     mov    es:word ptr [di],0001
PROGRAM.9: End;
  cs:0017 C9             leave
  cs:0018 C20400         ret    0004

Notice how this uses les to load the address to the actual parameter in
es:di and then uses that to modify the actual variable.

Variable parameters are called that as the actual parameter has to be a
variable. One cannot pass a constant (excluding typed constant) to it.
For example variable(2) would be illegal but value(2) would be perfectly
legal. This causes some problems as with string constants one would like
the efficient pass by reference method. Also in case of arrays (which
have to be variables) one might want protection against accidental
change and yet the pass by reference. For this reason newer versions of
TP have also constant parameters (const). They are constants (within the
procedure) and thus protected against change. So you can pass either a
constant or a variable. Also the compiler is free to choose optimal
method of passing (value for simple parameters and reference for complex
ones)

Quote
>  Pascal generates runtime code for all subprogram calls to set
>up these addresses and actually copies the program's data (to a location
>on the Stack) if a Value parameter is being passed.

Only on complex parameters. In simple ones the caller pushes the
parameter on the stack.

Quote
>  Thus, while Value
>parameters are safer to use, they are somewhat slower to have in
>execution and run a risk of using a lot of Stack when used.

Actually in case of simple parameters (like integer) value parameter can
use less stack space. Also whether it is slower even on arrays is not so
clear. The copying is pretty fast compared to constant pointer
references that variable parameter causes, especially if one compiles to
protected mode.

Quote
> (However,
>most academics favor Value parameters, because their use "protects"
>program data in subprograms where changing the data shouldn't be
>allowed...)

So it is best to use const. This does both. It generally is a bad
practice to use the value parameter as a local variable.

Quote
>   Note that all this is controlled through the subprogram's
>_declaration_, and the calls to the subprograms do nothing special.  That
>is, the calls to both Ref_Param and Val_Param will look the same:
>  Val_Param (Y);
>  Ref_Param (Y);
>but only Ref_Param can actually affect the value of Y when the call is
>made (Val_Param may alter what it's passed, but it's working with a copy
>of Y, not Y itself).

As I said this is incorrect in case of simple parameters or
arrays/records (excluding strings) of size of exactly 1, 2 or 4 bytes.
One can see the difference in the code I presented. (all strings are
passed as reference as the size of the actual and formal parameter can
be different if one uses $V-)

Osmo

Re:Parameter passing


JRS:  In article <MPG.f51efa7e2b90dd0989...@news.primenet.com> of Mon,
16 Feb 1998 06:41:01 in comp.lang.pascal.borland, Mike Copeland

Quote
<mrc...@primenet.com> wrote:
>> I am just starting to learn pascal and I was wondering if someone could
>> explain how parameter passing works, in plain english terms.

>   In Pascal, there are two classes of parameters: Value and Reference.  

Also, in BP7, TP7, there is "const".

Quote
>Both classes are passed to the procedure/function via pointers (the

Small "value" parameters are passed on the stack :

var j, k : byte ;
procedure x(var x : byte ; y : byte) ;
begin end ;
BEGIN
x(j, k) ;
end.

PROGRAM.5: x(j, k) ;
  cs:001D BF5000         mov    di,0050
  cs:0020 1E             push   ds
  cs:0021 57             push   di
  cs:0022 A05100         mov    al,[0051]
  cs:0025 50             push   ax
  cs:0026 E8D7FF         call   PROGRAM.X

The address of x, and the value of y, are pushed.

--
John Stockton, Surrey, UK.    j...@merlyn.demon.co.uk    Turnpike v1.12    MIME.
  Web <URL: http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
  Correct 4-line sig separator is as above, a line comprising "-- " (SoRFC1036)
  Don't Mail News to me.      Before a reply, quote with ">" / "> " (SoRFC1036)

Re:Parameter passing


Quote
> >> I am just starting to learn pascal and I was wondering if someone could
> >> explain how parameter passing works, in plain english terms.

> >   In Pascal, there are two classes of parameters: Value and Reference.  
> >Both classes are passed to the procedure/function via pointers (the
> >subprogram receives the _address_ of something, not its value), and the
> >key difference is what the pointer points to:
> >       - Value parameters pass the address of a _copy_ of the data.
> >       - Reference parameters pass the address of the _data_.

> Incorrect. Value parameters are not passed as pointers. The actual data
> is passed, not any address. (In case of complex parameters (like arrays)
> technically a pointer to the actual data is passed and then the
> initialization part of the procedure copies the data to a local variable
> but in practice this is mostly equivalent to passing the actual data)

   The TP/BP implementation may be so, but please reference the question
to which I was responding: I believe my reply _explained_the_concept_
adequately, and the fact that Borland implements a variation doesn't
change the concept, does it?  Perhaps I "overdid" my explanation, but I
didn't feel an answer needed to go quite into the extreme your
denunciation of my reply does... 8<{{

Quote
> To illustrate the difference in simple parameters, lets have some code:
> procedure Value(x:word);
> begin
>   x:=1;
> End;
> procedure Variable(x:word);
> begin
>   x:=1;
> End;
> var z:word;
> begin
>   value(z);
>   variable(z);
> End.
> Now lets see the code that is produced:
> Lets first view the calls:

   Does it really matter, in terms of the information I was trying to
convey in my reply?  Was my answer patently _wrong_ for his request?  I
don't think so...8<{{
   <Sigh> I really don't feel your ripping of my reply served the NG any
substantive good.

Re:Parameter passing


In article <MPG.f52dcdbe7038dd4989...@news.primenet.com>,

Quote
Mike Copeland <mrc...@primenet.com> wrote:
>> >> I am just starting to learn pascal and I was wondering if someone could
>> >> explain how parameter passing works, in plain english terms.

>> >   In Pascal, there are two classes of parameters: Value and Reference.  
>> >Both classes are passed to the procedure/function via pointers (the
>> >subprogram receives the _address_ of something, not its value), and the
>> >key difference is what the pointer points to:
>> >   - Value parameters pass the address of a _copy_ of the data.
>> >   - Reference parameters pass the address of the _data_.

>> Incorrect. Value parameters are not passed as pointers. The actual data
>> is passed, not any address. (In case of complex parameters (like arrays)
>> technically a pointer to the actual data is passed and then the
>> initialization part of the procedure copies the data to a local variable
>> but in practice this is mostly equivalent to passing the actual data)

>   The TP/BP implementation may be so, but please reference the question
>to which I was responding: I believe my reply _explained_the_concept_
>adequately, and the fact that Borland implements a variation doesn't
>change the concept,

What kind of Pascal does it the way you prescribed? I have never heard
any version pushing the address of simple types. That would be counter
productive. Value parameters are called that as the value, not the
reference is passed on the stack.

- Show quoted text -

Quote
>does it?  Perhaps I "overdid" my explanation, but I
>didn't feel an answer needed to go quite into the extreme your
>denunciation of my reply does... 8<{{

>> To illustrate the difference in simple parameters, lets have some code:
>> procedure Value(x:word);
>> begin
>>   x:=1;
>> End;
>> procedure Variable(x:word);
>> begin
>>   x:=1;
>> End;
>> var z:word;
>> begin
>>   value(z);
>>   variable(z);
>> End.
>> Now lets see the code that is produced:
>> Lets first view the calls:

>   Does it really matter, in terms of the information I was trying to
>convey in my reply?  Was my answer patently _wrong_ for his request?  I
>don't think so...8<{{

I disagree.

Quote
>   <Sigh> I really don't feel your ripping of my reply served the NG any
>substantive good.

See above.

Osmo

Re:Parameter passing


Quote
Mike Copeland wrote in message ...
>> I am just starting to learn pascal and I was wondering if someone
could
>> explain how parameter passing works, in plain english terms.

>   In Pascal, there are two classes of parameters: Value and
Reference.
>Both classes are passed to the procedure/function via pointers (the
>subprogram receives the _address_ of something, not its value), and

the

No. Trying to make value parameters look like reference parameters or
pointers only confuses the issue. They are different concepts.

Conceptually, when you have a value parameter, only the value is
passed. It becomes in effect a local variable of the subprogram,
initialised with the value being passed. The subprogram may modify
this local copy of the value without affecting the calling program,
exactly as is the case with other local variables. The calling program
may have an expression for a value parameter precisely because the
address is _not_ required.

For example,

function total(x:integer):integer;
  { x is a value parameter.
    Returns x + (x-1) + (x-2) + ... + 1
  }
Var
  Result : Integer;
Begin
  Result := 0;
  While (x>0) do
  Begin
    Result := Result+x;
    x := x-1;
      { the value parameter may be changed like any other local
        variable
      }
  End;
  total := Result;
End;

Begin
  Writeln(total(3+4));
    { An expression may be used for a value parameter
    }
End.

As an _implementation_ issue, BP7 has const parameters, which are
value parameters which the subprogram does not change the value of.
Conceptually they are the same as value parameters, assuming that we
do not wish to change the value of the parameter:

function total(const x:integer):integer;
  { x is still a value parameter, but one the programmer doesn't
    want to change.
    Returns x + (x-1) + (x-2) + ... + 1
  }
Var
  Result : Integer;
  i : Integer;
Begin
  Result := 0;
  For i := 1 to x do
    Result := Result+i;
  total := Result;
End;

Begin
  Writeln(total(3+4));
    { An expression may be used for a const parameter
    }
End.

However, since the programmer promises to the compiler that the value
of x will not change, the compiler may use a pointer if the type of
the parameter takes more than a few bytes of memory, for example if
the parameter is a string. Normally a value parameter is implemented
by putting it where local variables are put: on the stack (because for
the subprogram, it IS a local variable). If it would take a lot of
stack, putting the address of the data may be more efficient in some
cases. The differences are important, but not when learning what
parameters are. The compiler handles these differences. Conceptually
the value is passed, NOT a pointer.

On the other hand, reference parameters (also called Var parameters)
COULD be regarded as similar to pointers, if that helps you understand
them. (If not, forget the word "pointer" for now.)

A reference is a variable that occupies the same memory as another
variable of the same type. So the subprogram is told what the address
of the variable in the calling program is; within the subprogram you
can use the reference parameter as a normal variable but the important
thing is that you are dealing with a variable owned by the caller. The
compiler handles this for you: you just use the parameter as a
variable. But it's the caller's variable. So if you change the value,
the caller's variable is changed. This is useful if you want to pass
data back to the caller:

Procedure total(var x:integer);
  { Sets x to the total x + (x-1) + (x-2) + ... + 1
  }
Var
  Result : Integer;
  i : Integer;
Begin
  Result := 0;
  For i := 1 to x do
    Result := Result+i;
  x := Result;
    { This doesn't just change a local variable. x is a reference to
      whatever variable the caller said to use.
    }
End;

Var
  n : Integer;
Begin
  { An expression may NOT be used for a var parameter. So it has
    to be evaluated and put in a variable.
  }
  n := 3+4;
  total(n); { need a variable! Result gets put in n }
  Writeln(n);
End.

In this simple example, x is just an integer and total could be a
function. But sometimes you want to pass two separate values back, or
your compiler may not let you return values of the type that you want
(if it's a record, say). Then a var parameter is the way to go. If you
don't want to pass data back to the caller, use value parameters.

FP

Re:Parameter passing


In article <6ccj80$b5...@news.indigo.ie>,

Quote
Frank Peelo <fpe...@portablesolutions.com> wrote:

>As an _implementation_ issue, BP7 has const parameters, which are
>value parameters which the subprogram does not change the value of.
>Conceptually they are the same as value parameters, assuming that we
>do not wish to change the value of the parameter:

No, const parameters are neither value parameters nor reference
parameters. They are pure input parameters like the in parameters in
ADA. The underlying implementation can be either value or reference
depending on what is optimal. Because the parameters are const well
behaving programs work equally well on both. Ill behaving programs can
notice the difference. For example:

type Tarr=array[1..4] of byte;

var arr:Tarr;

Procedure xx(const a:tarr);
begin
  arr[1]:=1;
  writeln(a[1]);
End;

begin
  arr[1]:=2;
  xx(arr);
End.

The above code outputs 2 but it one changes the array size to 5 it
outputs 1. This is because array of 4 bytes is passed as value but array
of 5 bytes as reference. Directly modifying a variable used as actual
parameter is very ugly even in Pascal. In ADA or in TP with CONST it is
asking trouble plain and simple.

The const parameters are simply of completely different philosophy than
value or var.

Quote

>function total(const x:integer):integer;
>  { x is still a value parameter, but one the programmer doesn't
>    want to change.
>    Returns x + (x-1) + (x-2) + ... + 1
>  }
>Var
>  Result : Integer;
>  i : Integer;
>Begin
>  Result := 0;
>  For i := 1 to x do
>    Result := Result+i;
>  total := Result;
>End;

>Begin
>  Writeln(total(3+4));
>    { An expression may be used for a const parameter
>    }
>End.

>However, since the programmer promises to the compiler that the value
>of x will not change, the compiler may use a pointer if the type of
>the parameter takes more than a few bytes of memory, for example if
>the parameter is a string. Normally a value parameter is implemented
>by putting it where local variables are put: on the stack (because for
>the subprogram, it IS a local variable). If it would take a lot of
>stack, putting the address of the data may be more efficient in some
>cases. The differences are important, but not when learning what
>parameters are. The compiler handles these differences. Conceptually
>the value is passed, NOT a pointer.

No, conceptually one has an input parameter. Note that ADA (where const
parameters come from) does not even have reference parameters. Instead
they have inout parameters and leave even on them the implementation
open.  Ada also has output parameters that do not pass anything in. (Of
course the nice system has been ruined by requirement that only
procedures can use inout and out parameters)

Osmo

Re:Parameter passing


Quote
Osmo Ronkanen wrote in message <6cefam$...@kruuna.Helsinki.FI>...
>In article <6ccj80$b5...@news.indigo.ie>,
>Frank Peelo <fpe...@portablesolutions.com> wrote:

>>As an _implementation_ issue, BP7 has const parameters, which are
>>value parameters which the subprogram does not change the value of.
>>Conceptually they are the same as value parameters, assuming that we
>>do not wish to change the value of the parameter:

>No, const parameters are neither value parameters nor reference
>parameters. They are pure input parameters like the in parameters in
>ADA. The underlying implementation can be either value or reference
>depending on what is optimal.

Well, OK. I thought
- value parameters were ones where you get the value and can not
modify the caller's variables, and the caller therefore did not have
to use a variable for the parameter
- reference parameters were ones where the parameter is a variable
belonging to someone else which the subprogram can modify
(these without explicit reference to how the language is implemented)
and
- const parameters were an answer to the prayers of anyone (like me)
who was using var to avoid putting large variables on the stack when
calling a procedure even when there was no intention to modify them
(and this is very much an efficiency of implementation issue)

Guess I should have learned ADA.

Quote
> Because the parameters are const well
>behaving programs work equally well on both. Ill behaving programs
can
>notice the difference. For example:
>...

I've been trying trying to give up writing ill-behaved example
programs since the
"pchar modifying merged strings" ri-ra.

One introduction to ISO standard Pascal said "A parameter may be
declared to be protected; the code within the procedure or function
must then not contain statements which might change the parameter."
and goes on to mention protected var and protected value parameters. I
assumed const was the same as that except that the compiler makes the
decision about whether the parameter should be protected var or
protected value. So I was inclined to consider them one or the other,
I chose to consider them protected value parameters because you can
pass an expression. So, to the caller at least, they are the same as
value parameters (assuming you are considering the source code and not
using ugly tricks).

I wonder what the original poster wanted - an explanation of what
parameters are and how they should be used or a low-level explanation
of what bytes go where? I was assuming the former.

FP

Re:Parameter passing


In article <6ch5db$4e...@news.indigo.ie>,

Quote
Frank Peelo <fpe...@portablesolutions.com> wrote:

>Osmo Ronkanen wrote in message <6cefam$...@kruuna.Helsinki.FI>...

>Well, OK. I thought
>- value parameters were ones where you get the value and can not
>modify the caller's variables, and the caller therefore did not have
>to use a variable for the parameter
>- reference parameters were ones where the parameter is a variable
>belonging to someone else which the subprogram can modify
>(these without explicit reference to how the language is implemented)
>and

The point is that value and reference parameters are defined on the way
how they are passed, not on what their actual effect is. One could
produce a variable parameter even without passing any reference. (This
would require a C-style method where caller and not the procedure clears
the parameters from the stack.

...

Quote

>> Because the parameters are const well
>>behaving programs work equally well on both. Ill behaving programs
>can
>>notice the difference. For example:
>>...

>I've been trying trying to give up writing ill-behaved example
>programs since the
>"pchar modifying merged strings" ri-ra.

Still one should know the risks.

Quote

>One introduction to ISO standard Pascal said "A parameter may be
>declared to be protected; the code within the procedure or function
>must then not contain statements which might change the parameter."
>and goes on to mention protected var and protected value parameters. I
>assumed const was the same as that except that the compiler makes the
>decision about whether the parameter should be protected var or
>protected value.

You mean the ISO standard has both? Why? Were they drunk when they
decided on that?

Quote
> So I was inclined to consider them one or the other,
>I chose to consider them protected value parameters because you can
>pass an expression. So, to the caller at least, they are the same as
>value parameters (assuming you are considering the source code and not
>using ugly tricks).

>I wonder what the original poster wanted - an explanation of what
>parameters are and how they should be used or a low-level explanation
>of what bytes go where? I was assuming the former.

What's the difference?

Osmo

Other Threads