New Procedure [ HP Pascal/iX Programmer's Guide ] MPE/iX 5.0 Documentation
HP Pascal/iX Programmer's Guide
New Procedure
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;
(Example is continued on next page.)
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;
(Example is continued on next page.)
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.
MPE/iX 5.0 Documentation