- An function should produce a value and produces no side effect (similar to expression)
- A procedure is executed for its side effects and return no value (similar to statement).
10.1 Procedure Definition and Activation
- Procedure is a mechanism in a programming language for abstracting a group of actions or computations.
- The group of actions is called the body of procedure
- The procedure is defined by providing a specification or interface and a body.
- The specification gives the name, list of the types and names of its formal parameters
- declaration (C++), prototype (C) are separate from its body.
10.2 Procedure Semantics
- When a block is encountered during execution, it causes the allocation of local variables and other objects corresponding to the declarations of the block which called the activation record (or stack frame).
int x;
void B(void) {
int i;
i = x / 2;
...
} /* end B */
void A (void) {
int x, y;
...
x = y * 10;
B();
} /* end A */
int main () {
A();
return 0;
}
- The stack frame of global environment, block A and a procedure call of B
-----
| x | global environment
=====
| x |
----- Activation record of A
| y |
=====
| i | Activation record of B
-----
- parameters are sometimes called formal parameters and arguments are called actual parameters.
10.3 Parameter-Passing Mechanisms
pass by value
- value parameter behave as constant values during the execution of the procedure
- if the parameter has a pointer or reference type, then the value is an address and can be used to change memory outside the procedure. (array are implicitly pointer in C/C++).
int max (int x, int y) { return x > y ? x: y; }
max ( 10, 2 + 3); // replace the body of max as 10 > 5 ? 10: 5
pass by reference
- passes the location of the variable
- In C, operator & to indicate the location of a variable and the operator * to dereference a pointer.
void inc(int &x) { x++; } // pass by reference
inc(a);
/* is the same as */
void inc(int *x) { (*x)++; } // pass the pointer & deference the pointer
inc(&a); // pass the address of a
- In C++, reference argument must be l-value, that is , they must have known addresses.
void inc(int &x) { x++; }
inc(2); // error for C++ because it is not an l-value.
pass by value-result
- the value of the argument is copied and used in the procedure, and then the final value of the parameter is copied back out to the location of the argument when the procedure exits.
void p(int x, int y) { // v,t: x=1, y=1, a=1; r: x=a, y=a, a=1
x++; // v: x=2, y=1, a=1; r: x=a, y=a, a=2; t: x=2, y=1, a=1
y++; // v: x=2, y=2, a=1; r: x=a, y=a, a=3; t: x=2, y=2, a=1
} // v: x=2, y=2, a=1; r: x=a, y=a, a=3; t: x=2, y=2, a=2
main () {
int a = 1;
p(a, a);
...
}
/* at the end of main */
// v: pass by value, a = 1
// r: pass by reference, a = 3
// t: pass by value-result, a = 2
pass by name
- The argument is not evaluated until its actual use as a parameter in the called procedure.
int i;
int a[10];
void inc(int x) {
// v:x=1,i=1,a[1]=1,a[2]=2; r:x=a[1], i=1,a[1]=1,a[2]=2
// t:x=1,i=1,a[1]=1,a[2]=2; n:x=a[i], i=1,a[1]=1,a[2]=2
i++;
// v:x=1,i=2,a[1]=1,a[2]=2; r:x=a[1], i=2,a[1]=1,a[2]=2
// t:x=1,i=2,a[1]=1,a[2]=2; n:x=a[i], i=2,a[1]=1,a[2]=2
x++;
// v:x=2,i=2,a[1]=1,a[2]=2; r:x=a[1]+1,i=2,a[1]=2,a[2]=2
// t:x=2,i=2,a[1]=2,a[2]=2; n:x=a[i]+1,i=2,a[1]=1,a[2]=3
}
// v:x=2,i=2,a[1]=1,a[2]=2; r:x=a[1]+1,i=2,a[1]=2,a[2]=2
// t:x=2,i=2,a[1]=2,a[2]=2; n:x=a[i]+1,i=2,a[1]=1,a[2]=3
main() {
i = 1;
a[1] = 1;
a[2] = 2;
inc(a[i]);
return 0;
}
/* at the end of main */
// v: pass by value : i=1, a[1]=1, a[2]=2
// r: pass by reference : i=2, a[1]=2, a[2]=2
// t: pass by value-result: i=2, a[1]=2, a[2]=2
// n: pass by name : i=2, a[1]=1, a[2]=3
10.4 Procedure Environments, Activations, and Allocation
10.5 Dynamic Memory Management
10.6 Exception Handling and Environments
10.7 Case Study: Processing Parameter Modes in TinyAda
Additional Notes
Exercise
Other Resources