 |
» |
|
|
 |
The predefined procedure new takes a
pointer variable as a parameter, allocates a variable of the type
that the pointer references, and "points" the pointer at the new
variable (that is, new assigns the address
of the new variable to the pointer). The program can then access
the new variable by dereferencing the pointer. Example 1 PROGRAM prog; TYPE iptr = ^integer; cptr = ^char; rptr = ^real; VAR ivar : iptr; {pointer to a dynamic integer variable} cvar : cptr; {pointer to a dynamic character variable} rvar : rptr; {pointer to a dynamic real variable} BEGIN new(ivar); {allocate new integer variable on heap} new(cvar); {allocate new character variable on heap} new(rvar); {allocate new real variable on heap} ivar^ := 375; {assign value to new integer variable} cvar^ := 'c'; {assign value to new character variable} rvar^ := 3.7; {assign value to new real variable} END. |
The new variable is allocated space on the heap. A run-time
error occurs if the heap cannot accommodate the variable. If the new variable is a record with variant fields, you can
specify the variant that you want with a tag. The tag only tells
the new procedure how much space to allocate;
it does not cause the new procedure to assign
the value of the tag to the new variable's tag field. Example 2 PROGRAM prog; TYPE marital_status = (single, married); rec = RECORD lname, fname : string[30]; kids : 1..20; |
CASE mstat : marital_status OF single : (divorced, widowed, engaged : Boolean); married : (how_many_times: 1..10; how_long_this_time : 1..100); END; recptr = ^rec; VAR person1, person2, person3 : recptr; BEGIN new(person1,single); WITH person1^ DO BEGIN lname := 'Doe'; fname := 'John'; kids := 0; mstat := single; {New does not make this assignment} divorced := FALSE; widowed := FALSE; engaged := FALSE; END; new(person2,married); WITH person2^ DO BEGIN lname := 'Smith'; fname := 'Jane'; kids := 3; mstat := married; {New does not make this assignment} how_many_times := 1; how_long_this_time := 9; END; new(person3); END. |
The new record variable person1^
has space for the fixed fields lname,
fname, kids,
and mstat, and
for the single
variant fields divorced,
widowed, and
engaged. The new record variable person2^
has space for the same fixed fields, and for the married
variant fields how_many_times
and how_long_this_time. If the new variable is a record with nested variant fields,
you can specify a tag for each variant. If you do, you must specify
them in the order that they are declared, and you cannot leave gaps
in the sequence. Example 3 In this program, the declaration order of the tag fields is
obviously t1, t2
or t1, t3. PROGRAM prog; TYPE r = RECORD f1 : integer; CASE t1 : (a,b) OF a : (arec : RECORD i : integer; CASE t2 : (c,d) OF c : (j : integer); d : (k : real); END {arec} ); b : (brec : RECORD CASE t3 : (e,f) OF e : (l : real); f : (m : char); END {brec} ); END; {r} rptr = ^r; VAR v : rptr; BEGIN new(v); new(v,a); new(v,a,c); new(v,a,d); new(v,,d); {illegal must specify a} new(v,d); {illegal must specify a} new(v,b); new(v,b,e); new(v,e,b); {illegal tags are not in order of declaration} new(v,b,f); new(v,a,f); {illegal with variant a, variant f is impossible} END. |
Example 4 This program is semantically equivalent to the program in
the immediately preceding example (Example 3), and the declaration
order of the tag fields is the same. PROGRAM prog; TYPE arectype = RECORD i : integer; CASE t2 : (c,d) OF c : (j : integer); d : (k : real); END; brectype = RECORD CASE t3 : (e,f) OF e : (l : real); f : (m : char); END; r = RECORD f1 : integer; CASE t1 : (a,b) OF a : (arec : arectype); b : (brec : brectype); END; rptr = ^r; VAR v : rptr; BEGIN new(v); new(v,a); new(v,a,c); new(v,a,d); new(v,,d); {illegal must specify a} new(v,d); {illegal must specify a} new(v,b); new(v,b,e); new(v,e,b); {illegal tags are not in order of declaration} new(v,b,f); new(v,a,f); {illegal with variant a, variant f is impossible} END. |
You do not have to specify tag fields. If you omit them, new
allocates enough space for the largest possible variant, wherever
there are variants. This allocation is the default allocation for
variables of the particular record type. If you use tags to specify smaller variants, new
allocates less than the default allocation to the new variable.
The advantage to using tags is that you save space. The disadvantage
is that the new variable cannot appear in an assignment statement,
or as an actual parameter. (Assignment statements and formal parameters
use the default allocation.) It is legal for the fields of the new
variable to appear as actual parameters, and to be used in a field
by field assignment. Example 5 PROGRAM prog; TYPE rec = RECORD CASE t : (a,b) OF a : (a1,a2 : integer); b : (b1,b2,b3,b4,b5,b6 : integer); END; recptr = ^rec; VAR small, small2, large, default : recptr; PROCEDURE p (r : rec); EXTERNAL; BEGIN new(small,a); {allocates only enough space for smaller variant, a} new(small2,a); {allocates only enough space for smaller variant, a} new(large,b); {allocates enough space for larger variant, b} new(default); {allocates enough space for larger variant by default} WITH small^ DO BEGIN t := a; a1 := 350; a2 := 609; END; WITH large^ DO BEGIN t := b; b1 := 350; b2 := 609; END; |
default^.t := a; default^ := small^; {illegal} default^.t := b; default^ := large^; {illegal} small2^ := small^ {still illegal even though the spaces are allocated } {using the same tag } small2^.a1 := small^.a1 {legal} small2^.a2 := small^.a2 {legal} p(small^); {illegal} p(large^); {illegal} p(default^); {legal} END. |
The pointer parameter of new can belong
to a PACKED structure. Example 6 PROGRAM prog; TYPE ptr = ^integer; pa = PACKED ARRAY [1..10] OF ptr; pr = PACKED RECORD f1,f2 : ptr; END; VAR v1 : pa; v2 : pr; BEGIN new(v1[5]); new(v2.f1); END. |
A pointer created by new can be compared
to another pointer for equality or inequality only. This is also
true of a pointer created by mark. For more
information on relational operators, refer to the HP
Pascal/iX Reference Manual or the HP Pascal/HP-UX
Reference Manual, depending on your implementation.
|