Imperative Programming — Procedure Activations Steven Zeil Oct. 4, 2001
Contents 3
Procedure Activations 3.1 Basics . . . . . . . . . . . . . . . 3.1.1 Procedures (Subroutines) . 3.1.2 Bindings . . . . . . . . . 3.2 Parameter Passing . . . . . . . . . 3.2.1 Call-by-Value . . . . . . . 3.2.2 Call-by-Reference . . . . 3.2.3 Call-by-Value-Result . . . 3.2.4 Call-by-Name . . . . . . . 3.2.5 Intent . . . . . . . . . . . 3.3 Scopes . . . . . . . . . . . . . . . 3.3.1 Scope . . . . . . . . . . . 3.4 Activation Records . . . . . . . . 3.4.1 Anatomy of an Activation 3.5 Case study: C . . . . . . . . . . . 3.6 Case study: Pascal . . . . . . . . 3.6.1 Access Link . . . . . . . . 3.6.2 Displays . . . . . . . . .
Imperative Languages
3.1 . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
1. Procedures 1 1 2. Bindings 1 1 2 2 3.1.1 Procedures (Subroutines) 2 Two kinds of procedures: 3 • Function procedures return a value. 3 4 • Proper procedures do not. 5 5 A procedure has 4 parts: 8 1. name of procedure 8 10 2. formal parameters 11 3. body, consisting of 12 12 • local declarations • statement (list) 4. an optional return type
1. Statements
i n t f a c t ( i n t n ) { return n∗ f a c t ( n −1);}
2. Data Structures
FUNCTION F a c t ( n : i n t e g e r ) : i n t e g e r ; BEGIN F a c t : = n ∗ F a c t ( n −1) END
3. Procedure Activations
3
Basics
Procedure Activations 1. Basics
3.1.2
2. Parameter Passing
A binding is an association of a value with some name/entity. In any program, “names” must somehow be bound to their
3. Scopes
Bindings
• types
4. Activation Records
• locations (l-values)
5. Case study: C
• value (r-values)
6. Case study: Pascal
Some of these bindings are static, others dynamic.
1
2
Imperative Programming — Procedure Activations
• Cannot be used to send values back to the caller
Some Common Bindings scope
name
3.2
activation
declaration
state
l-value
r-value
p r o c e d u r e BadSwap ( x , y : T ) ; var temp : T ; begin temp : = x ; x : = y ; y : = temp ; end ;
Parameter Passing
• Passing large objects (e.g., arrays) is time-consuming A procedure call supplies actual parameters to be passed to the called routine. Within the procedure body, these are referenced via the formal pa3.2.2 Call-by-Reference rameter names. i n t f a c t ( i n t n ) { return n∗ f a c t ( n −1);} .. . int i = fact (23); 23 is the actual parameter. n is the corresponding formal parameter The process of matching formal parameters to actuals is called parameter passing. There are many techniques for parameter passing: • Call-by-Value
In call-by-reference, the formal parameter name is bound to the lvalue of the actual (it becomes a synonym for the actual). • Pascal var parameters are call-by-reference. • FORTRAN uses call-by-reference.
• C programmers fake it by passing pointers (but the pointers are actually passed by value). • C++ has reference types, which emulate call-by-reference.
• Call-by-Reference • Call-by-Value-Result • Call-by-Name Alternatively, we can classify parameter passing by the programmer’s intent.
3.2.1
Call-by-Value
In call-by-value, the r-value of the actual parameter is copied into a local l-value within the called routine. For a procedure P with formal parameter x, a call P(E ) ;
Call-by-reference has constant overhead, can be used for output: p r o c e d u r e Swap ( var x : T ; var y : T ) ; var temp : T ; begin temp : = x ; x : = y ; y : = temp ; end ; C-simulation of call-by-reference: v o i d swap ( T ∗ x , T ∗ y ) { T temp ; temp = ∗ x ; ∗ x = ∗ y ; ∗ y : = temp ; }
is equivalent to x : = E; body o f P ; i f P i s a function , return a result ; Call-by-value is the primary passing mechanism in Pascal, C, and C++. Limitations:
C++’s call-by-reference: v o i d swap ( T& x , T& y ) { T temp ; temp = x ; x = y ; y : = temp ; } Limitations of call-by-reference:
3
Imperative Programming — Procedure Activations
• Can only be applied to actual parameters that have l-values. – OK for Swap(a,b) where a and b are variables – OK for Swap(A[i], Rec.field) – Not allowed: Swap(a, 2+3) – Not allowed: Swap(1,2)
Properties of Value-Result • Somewhat more predictable behavior in the presence of aliasing. • Can be used for output • High overhead (2 copies) for large objects
• Minimal protection against inadvertent changes Value-Result & Aliasing Aliasing Aliasing refers to the ability to manipulate the same r-value through different names/expressions. Call-by-reference can result in unexpected behavior due to aliasing.
Reference & Aliasing void addVectors ( const Vector & a , const Vector & b , Vector & c ) { / / Vector addition : c = a + b assert ( a . size () == b . size ( ) ) ; / / make c e m p t y c . e r a s e ( c . b e g i n ( ) , c . end ( ) ) ; for ( int i = 0 ; i < a . size ( ) ; + + i ) / / append a [ i ]+b [ i ] t o c c . push back ( a [ i ] + b [ i ] ) ; }
What happens if the application code says: // x = x + y; addVectors ( x , y , x ) ;
procedure ad dV ec to rs ( a , b , c : in out Vector ) i s b e g i n −− V e c t o r add : c : = a + b c . c l e a r ( ) ; −− make c e m p t y for i in 1 . . a ’ l e n g t h loop c . push back ( at ( a , i ) + at ( b , i ) ) ; end l o o p ; end a d d V e c t o r s ; If application does addVectors ( x , y , x ) ; the function will run properly, but final value of x depends on which parameter gets copied last.
3.2.4
Call-by-Name
Call-by-name is equivalent to passing the actual text of the actual parameter to the procedure, substituting it for each occurrence of the formal parameter name: # d e f i n e min ( x , y ) ( x