Content deleted Content added
short circuit compiler directive $B |
enhancing example of parameter passing and adding IMPORTANT section on the stack management for calls |
||
Line 505:
</syntaxhighlight>
Pascal has two different types of parameters: pass-by-value, and pass-by-reference (VAR). In both cases the variable name is used when calling (no need of address operator).
<syntaxhighlight lang="pascal">
function f(z: integer; var k: integer): integer; // function accepts two integers, one by value, one by reference
Begin
z:=1; // outer variable u will not be modified, but local value is modified in the function's scope
k:=1; // outer variable t will be modified because it was passed by reference
// up to here, z exists and equals 1
End;
x := f(u,t); // the variables u and t are passed to the call : the value of u and the reference to t
</syntaxhighlight>
Line 514 ⟶ 520:
<syntaxhighlight lang="c">
int f(int z, int *k)
z=1; // idem Pascal, local value is modified but outer u will not be modified
*k=1; // variable referenced by k (eg, t) will be modified
// up to here, z exists and equals 1
}
x = f(u,&t); // the value of u and the (value of) address of variable t are passed to the call
</syntaxhighlight>
One of the most important difference between C and Pascal is the way they handle the parameters on stack during a subroutine call :
This is called the '''calling convention''' :
PASCAL-style parameters are pushed on the stack in left-to-right order.
The STDCALL calling convention of C is a variation of the PASCAL calling convention in which are pushed on the stack right-to-left.
Pascal-style procedure call is made with :
. caller pushing parameters into the stack in left-to-right order (opposite of __cdecl)
. calling the function
. stack is cleaned up by the callee
<code>
; example of pascal-style call.
; NOTE: __stdcall would push the arguments in reverse order.
push arg1
push arg2
push arg3
call function
; no stack cleanup upon return: callee did it
</code>
The advantage of PASCAL call over STDCALL is that the code is slightly smaller, though the size impact is only visible in large programs, and that recursion works faster.
Variadic functions are almost impossible to get right with PASCAL and STDCALL methods, because only the caller really knows how many arguments were passed in order to clean them up.
C allows for functions to accept a variable number of parameters, known as [[variadic function]]s, using a clumsy mechanism of <code>va_list ap;</code>, <code>va_start(ap, count);</code>, <code>va_arg(ap, ''type'');</code> with limited ''type'' availability (example : nothing for <code>bool</code>)
<syntaxhighlight lang="c">
Line 525 ⟶ 559:
</syntaxhighlight>
The function <code>f()</code> uses a special set of functions (<code>varargs</code>) that allow it to access each of the parameters in turn.
Pascal and C also have some variadic I/O functions, for instance <code>WriteLn()</code> and <code>printf()</code>.
Modern Pascals enable a variable number of parameters for functions :
<code>
procedure writeLines(const arguments: array of const); // parsed via : for argument in arguments do
</code>
They also enable to interface with varargs C functions :
<code>
Function PrintF1(fmt : pchar); cdecl; varargs; external 'c' name 'printf';
</code>
C
<syntaxhighlight lang="c">
Line 542 ⟶ 587:
</syntaxhighlight>
In Pascal
<syntaxhighlight lang="pascal">
|