Transcript Lecture 7

Procedures and Control Flow
CS351 – Programming Paradigms
Recap

Recall the various methods of control flow:
Sequencing, Selection, Iteration etc.
 Subroutines (Methods) can also be used to
implement some form of control flow.
 However subroutines not only abstract the
idea of control but also data ie a subroutines is
an abstraction to perform a well defined
operation.
Subroutines

These are the most common control
abstraction in most programming languages.
 Some point in the program, known as the
caller calls the subroutine and then waits for it
to finish.
 Most subroutines are parameterised:


Arguments passed are actual parameters
Arguments used to define a subroutine are called
formal parameters.
Subroutines cont…

A subroutine that returns a value is called a
function.
 A subroutine that does not return a value is
called a procedure.
 We will look at:




Calling subroutines
Parameter Passing
Variable Argument lists
Generic Methods (via Java and C++)
Calling Subroutines
SP
Temps.
D
SP
Args.
FP
Local Vars.
C
Misc.
Return addr
B
A
FP
The main method calls subroutine A. Subroutine
A then calls B, which calls C.
C then calls D. The Frame Pointer FP, is used to
tell which is the current active subroutine while
the stack pointer SP, tells us where to push new
information about the subroutines.
Stack Elements

Each stack element from the previous slide is
known as an activation record.
 Each activation record takes (at least) the
following into account:



Arguments and Return values
Temporaries
Bookkeeping Information
Calling Subroutines
The caller:
1.
saves any registers whose values are needed after
the call.
2.
computes the values of arguments and moves them
into the stack.
3.
uses a special subroutine call instruction to jump to
the subroutine, while passing the return address to
the stack.
Calling Subroutines cont…
After the subroutine has completed:
1.
2.
3.
4.
The return value is moved into a reserved location in
the stack.
FP and SP are restored.
Jump back to the return address.
The return value (if any) is moved to whereever it is
needed.
Optimisations for C/C++


To help overcome the need for stack activation for
frequently used subroutines, it is possible to expand
the subroutine into the code to speed up the operation.
In C/C++ the inline keyword is used to achieve this.
inline int max( int a , int b ) { return a > b ? a : b }
main()
int a = max ( 5 , 6 );
main()
a = 5>6 ? 5:6;
Parameter Passing



Parameters allow subroutines to take arguments.
These arguments may control certain aspects of the
subroutines behaviour or specify the data on which
they operate.
We will look at



Parameter Passing Modes
Default and missing parameters
Variable length arguments lists
Parameter Passing Modes

There are two major type of parameter passing
modes:
1.
2.

Pass by value
Pass by reference
Suppose we have some fragment of code
P(x);



/* x is some global variable */
We wish to pass x as a parameter to subroutine P.
Should we provide P with a copy of x or with the
address of x?
Do the different methods make any difference?
Parameter Passing by Value

Each actual parameter is assigned into the
corresponding formal parameter is called.
 Once this happens the two are independent
and there are no side effects.
In Java:
void swap(int a, int b) { tmp = a; a = b; b = tmp; }
main() {
int a = 8; int b = 6;
swap(a,b);
System.out.println(a+ ‘’ +b);
Parameter Passing by Reference

Each formal parameter introduces, within the
body of the subroutine, a new name for the
corresponding actual parameter.
 This means that the actual parameter and the
formal parameter alias the same data or
object.
 In most languages the parameter passed by
reference must be an l-value, it cannot be the
result of an expression or any value without
and address.
Parameter Passing by Reference
In C/C++:
void swap( int a, int b ) { tmp = a; a = b; b = tmp; }
main(){
int a = 8; int b = 6;
swap(a,b);
std::cout<<a<“ “<<b<<std::endl;
Answer?
8 6 – Why?
We need to tell C++ pass by reference!
void swap ( int& a, int& b ) { tmp = a; a = b; b = tmp; }
main() {
int a = 8; int b = 6;
swap ( *a, *b );
Parameter Passing
x : int
procedure f ( y : int )
y := 3
print x
…
x:=2
f(x)
print x
 Call by value – answer?
 Call by reference - answer?
References in C++

We have already seen the use of the & reference
operator.
void swap (int &a, int &b ){ … }

In C++, reference parameters can be made to be read
only through the use of the const keyword.
int * rd_only ( const int& a ) const
{ return *a; }

Another example:
int i; int & j = i;
i = 2; j = 3;
std::cout << i ;
Default Parameters


It is possible to have subroutines that have default
formal parameters in the absence of actual
parameters.
For example in C++:
int f(int = 0);
void g()
{ int a = f(1); // ok
int b = f(); // ok, default argument used
}
Variable Number of Arguments




Lisp, Python, C/C++ and Java all support the ability to
create subroutines that can accept a variable amount
of arguments passed.
The printf function in C is defined as follows:
int printf( char * format, … )
The three dots, … , is known as an ellipses and is a
valid keyword in the language ( and in Java!).
The ellipses tells the compiler to expect a variable
amount of arguments.
Variable Arguments in Java
static void print_lines ( String… lines )
{
System.out.println(lines.length);
for (String s : lines)
System.out.println(s);
}
print_lines(“This is”, “an example”, “of multiple” , “arguments!” );
 Doing this in Java is easy, in C/C++ not as easy, we will do some
in the lab.
 Java demands that all of the elided arguments are of the same
type
Generics

On Thursday we will discuss the issue of
implementing generic methods in C++
and Java.