CS5113: Advanced Programming Languages
Week 12
Static vs. Dynamic Scope Example:
program main;
integer m;
procedure P ( );
write m;
end;
procedure Q ( );
integer m;
m := 0;
P ( );
end;
begin
m := 1;
P ( );
Q ( );
end.
Languages
Fortran – static scoping, all variables local, explicit use of COMMON block for globals
Pascal – static scoping, functions and procedures delimit scope, inheritance of globals for nesting (static)
procedure A
procedure B
I : integer; {I is unknown to A and D, local to B, non-local to C}
procedure C
:
end C;
end B;
procedure D
end D;
end A;
A can call A, B, D
B can call A, B, C
C can call A, B, C
D can call A, B, D
Some languages (Euclid and Modula)
-
no automatic inheritance
-
need explicit import list
-
EXAMPLE:
proc
import I from B;
-
redundant, no advantages (except maybe in classes?)
Ada – static scoping, scope delimited by a procedure, function, block, packages and tasks
C++ - static scoping, scope delimited by a function, for loops, classes
static scoping anamoly: hole-in-scope
-
if variable name reused, no way can acess to original variable of same name be gained
-
ADA takes care of it: use a qualification to see original (prefix with scope name)
-
EXAMPLE:
procedure X is
A : real;
procedure Y is
A: real;
begin
A := 1; {refers to Y’s A}
X.A :=2; {refers to X’s A}
end y;
begin
…
end X;
EXTENT – life of memory location
-
static (during entire program execution)
-
end of block
-
end of function/procedure
-
end of main procedure (like 1)
-
controlled (free/alloc/new statement or dealloc/delete/dispose)
-
auto collection (free/alloc/new, but no dealloc/delete/dispose)
ALGOL60: all local variables lost on block exit
Pascal: end of procedure, end of main, and controlled (new/dispose)
FORTRAN: homework
PL/I : static
C++: end of loops(block), end of function, end of main and controlled
ALGOL and Modula – have OWN variables
-
not deallocated on block exit, retains value for subsequent entries
-
useful for test if first time in block or not
-
can be simulated: declare variable in outer block, pass back and forth
Pointer variables -
some objects have extents which exceed scope of their name
-
not all storage management is done using a stack
-
some storage management is done using a heap: a pool of available storage for created objects whose extent doesn’t obey LIFO rules
P ascal
originally
-
no dispose
-
son once all pointers to storage from name variable lost, storage of anonymous variables unretrievable for duration of program
now
-
with dispose
-
responsibility on programmer to return storage
Algol, Java, Lisp -
no explicit freeing statement
-
garbage collection unpredictable
-
slows program
Parameters
pass by value parameters
-
only way in C++
-
first half of pass-by value-result,
-
same as a value parameter in Pascal
-
or an in parameter in ADA
pass by reference parameters
-
same as var parameter in Pascal
-
simulated in C++ with & operator in parameter list
pass by name parameters
FORTRAN
T he fact that I changed to 2 has no effect on EL, since reference of A(I) computed at runtime.
Suppose we use pass by reference (not value-result)
Assign K = 2 => I =2 //has effect of setting I to 2
EL = 0 => A(1) = 0 //has effect of setting A(1) to 0
same program in ALGOL
implementation of pass by name
-
not really copied, that would be inefficient, pass address of a code sequence (called a THUNK)
-
useful for certain applications
-
STUDY problem: changed ALGOL segment, so it has effect of FORTRAN segment
pass by name dangerous:
ALGOL example
procedure swap (x, y)
integer x, y;
begin
integer t;
t := x;
x := y;
y := t;
end;
copy rule copy rule
swap (i, j); t := i; swap (j, i); t := j;
i := j; j := i;
j := t; works i := t; works
swap (A[i], i) t := A[i]; swap(i, A[i]); t := i;
A[i] : i; i := A[i];
i := t; works A[i] := t; doesn’t work!!!
TRACE i = 1 A[1] = 27
t = 1
i = 27
A[27] = 1 OOPS!
Design mistake in ALGOL - no way to design an ALGOL swap procedure that always works!
Summary
pass by value:
- formal bound to value of actual at time of call.
-
value parameter takes a snapshot of actual, later changes in actual’s values not seen by caller
-
early inspection time
pass by reference:
-
formal bound to reference of actual at time of call.
-
reference can’t vary after, although value stored at reference can
-
early inspection time
-
less variability and less flexibility, but less dangerous than pass-by-name
pass by name:
-
formal bound to a thunk for the actual at time of call
-
although this can’t vary, each time it is evaluated it may return a different reference and consequently a different value
-
late inspection time
Aliasing in connection with procedures -
simplest form: procedure called with an actual parameter same name as a global variable that appears in procedure’s body
Avoid aliasing? Don’t allow automatic inheritance of globals. Instead use IMPORT clause
Share with your friends: |