To date, most activity porting PL/I code to Iron Spring PL/I has been mainframe code. We recently looked at porting software from IBM PL/I for Windows and OS/2 to Iron Spring PL/I for Linux. Two problems immediately stood out.
Friday, July 29, 2022
Saturday, July 16, 2022
What is this thing?
What is this thing?
The PL/I preprocessor is a general-purpose macro processor. It was designed to add macro capability to the PL/I language, but in fact has the ability to operate on nearly any text data (exceptions noted below). The PL/I preprocessor includes functionality similar to the C preprocessor, but is much more powerful, including looping and branching absent from C.The preprocessor is not part of the PL/I language standard, but many compilers include a version similar to IBM’s, perhaps with some differences.
Friday, July 15, 2022
Down the rabbit hole
One pill makes you larger
And one pill makes you small
After fifty years, PL/I still retains it's capacity to astound me.
Most recently I have been poking around in the dusty corners of the based storage class.
We all know its usefulness for, for example, list processing, allocating and traversing a linked list of items. Often it is used to allocate a string or array whose length or upper bound is not known at run time, for example the following allocates a string of length 1024.
DECLARE size FIXED BINARY;
DECLARE string CHARACTER(size) BASED(p);
size = 1024;
ALLOCATE string SET(p);
What IS surprising, however is that the "size" of the based variable can change without reallocation. Consider the following program fragment:
[1] dcl i fixed bin(31);
[2] dcl (p,q) ptr;
[3] dcl s char(i) based;
[4] i = 8;
[5] allocate s set(p);
[6] put skip list('size of p->s ' || trim(storage(p->s)) );
[7] i = 4;
[8] allocate s set(q);
[9] put skip list('size of q->s ' || trim(storage(q->s)) );
[10] put skip list('size of p->s ' || trim(storage(p->s)) );
As expected, line 5 allocates a string of length 8, line 6 prints
"size of p->s 8"
Line 8 allocates a second string of length 4, line 9 prints
"size of q->s 4"
There are now two strings of different lengths allocated. However, line 10 prints
"size of p->s 4"
Now add the following lines:
[11] i = 16;
[12] put skip list('size of q->s ' || trim(storage(q->s)) );
What is the size of the area printed? No additional allocations have taken place.
The value is "size of q->s 16"!
This isn't quite as much of a problem if the string length is shortened, but if it's lengthened all kinds of bad can result.
For adjustable based data, the lengths and bounds expressions from the declaration are re-evaluated each time the variable is referenced. Who knew? Actually, the Multics PL/I language reference makes this clear, but the various IBM manuals seem to gloss over it.