11.3. Data Lifetime.   

Example to provoke thought:

     procedure fish;

var q,p:ptr_to_sometype;
begin
new(p); q p; `first q;`
for I 1 to 10 do
begin

new(p); q.link p; p.info ____________
end;
end;

What happens to this linked list? Is it lost because the data frame on the stack is lost? Or is the linked list still there complete with its info? What if we added "first q"; at line (3) and first was global? Does this mean that the pointer "first" now points to garbage?

Each record is obtained from the Heap not the Stack.

Hence pointer "first" points at valid information.
If first was not set to q then the linked list would
be lost forever but intact.

Languages, like FORTRAN-66, which do not use the stack to hold local variables must use set = static memory locations.

--------------
| Code for | Subroutine fish
| FORTRAN | Integer I,J
| Subroutine | Do 10 I=1,20
| Fish | 10 J=J+1
-------------- Return
| | End
| I | return address
--------------
| J | & local variables
-------------- stored in static locations
|Return address|
--------------

If MAIN calls FORTRAN-66 subroutine (A) which calls (B) which

(by accident perhaps) calls (A) again then
(1) Location holding return addr to main is
overwritten by 2nd calling of A: no recursion.
(2) All local variables are (perhaps) altered from previous
values. Therefore saving of environment is in static memory.
: recursion does not work properly.

(Modern languages like Java just have old environment on stack and create new one on stack. A return just pops new one off stack.)

(Some microprocessors which ran Pascal did not have good stack manipulation instructions (8080,Z80) and hence could not easily use the full power of the stack. Many had to resort to the FORTRAN-66 method of storing variables and parameters. In that case it was necessary to tell the Pascal compiler that the procedure was recursive (either directly or indirectly) and in some cases how recursive it was!! This was so it could reserve enough space to hold the appropriate number of environments.)

Example to provoke more thought:


a: record
procedure
fish2 info:integer;
var info2:array...;
p:ptr_to_sometype; a:sometype; end
begin

/* some code in here to set "first"
(==a global of type:ptr_to_sometype) pointing at/to
a (== a local variable on stack of some type) */
end;

What does "first" point to when procedure fish2 returns to calling routine?

In languages like Pascal, Algol 60, etc the type of result which can be

returned from a procedure or assigned to a location is
restricted so that there can be no pointers to a procedures
activation data frame when the procedure environment no longer
exists.

However, in C and Algol 68 it is syntactically possible to do the above.

procedure fish_in_C; We have a pointer to something that no
var a:sometype; longer exists! This is called a
begin dangling pointer and compile time/run
global_pointer=&a time checks must be made to determine
end; /* Quite legit in C */ legality of assignment.

Now the compiler or some runtime support code must identify the lifetime of an object and see whether it is possible to do the assignment. The lifetime of something in the heap is potentially infinite whilst the lifetime of some object on the stack is only that of the procedure activation in whose data frame it resides.

No procedure activation can be permitted access to a pointer

which leads to an object with a shorter lifetime than itself.
--> No pointer must lead from an older data frame to a younger.

The lifetime is easy to measure.

Compile time: higher textual levels --> shorter lifetime.
Runtime: higher the data frame address on stack, the younger the data
frame and therefore shorter the lifetime.
/* Assuming stack starts at low address and grows toward high address */