With the last IBM PL/I compiler for Windows, i have an error at line
09:
Code:
01: SWAP: PROCEDURE(pIN,ilen);
02: DECLARE
03: PIN POINTER,
04: ILEN BIN FIXED(31), /* length in byte */
05: I BIN FIXED(31);
06:
07: BEGIN;
08: DECLARE
09: C_ARR(ILEN) CHAR(1) BASED(PIN),
10: C_HELP CHAR(1);
11: DO I = 1 TO ILEN -1 BY 2;
12: C_HELP = C_ARR(I);
13: C_ARR(I) = C_ARR(I+1);
14: C_ARR(I+1) = C_HELP;
15: END;
16: END;
17: return;
18: END SWAP;
19:
20: /* Source Code from http://www-wnt.gsi.de/CHARMS/SATAN/graf.htm */
21:
It compile with older compiler...
Compiler Version:
=> "IBM(R) PL/I for Windows 7.6"
Compiler output:
=> (09:1) : IBM2209I S Use of nonconstant extents in BASED variables
without REFER is invalid except on scalars.
How to resolve this problem ?
Thanks,
kris
> 08: DECLARE
> 09: C_ARR(ILEN) CHAR(1) BASED(PIN),
> 10: C_HELP CHAR(1);
(snip)
> It compile with older compiler...
> Compiler Version:
> => "IBM(R) PL/I for Windows 7.6"
> Compiler output:
> => (09:1) : IBM2209I S Use of nonconstant extents in BASED variables
> without REFER is invalid except on scalars.
> How to resolve this problem ?
Easiest is to cheat like everyone used to do in Fortran.
Dimension it (1) and be sure SUBSCRIPTRANGE is disabled, at
least for the statements that use it. Since there are no variables
after it in the structure (well, no structure) then it won't
cause any problems.
-- glen
Thanks glen, your solution is good for the first example.
I'm sorry but my example was bad...
01: %PROCESS LANGLVL(SAA2);
02: %PROCESS MARGINS(1,100) PP(MACRO);
03: %PROCESS LIMITS(EXTNAME(100),FIXEDBIN(31,63),FIXEDDEC(15,31),NAME
(100));
04: %PROCESS INCLUDE(EXT('CPY','INC','MAC'));
05: %PROCESS OR('|') NOT('!ª^');
06:
07: ProtoPliPackage: package;
08: default range(*) fixed;
09:
10: %include Tools;
11:
12: foo: proc(arr);
13: dcl arr(*) char(1) connected;
14: /* ... */
15: display(size(arr));
16: /* ... */
17: end foo;
18:
19:
20: ProtoPli: proc options(main);
21:
22: dcl str char(32767) init('0123456789');
23: dcl address pointer init(null());
24: dcl len fixed bin(31) init(length(str));
25:
26: dcl array1(len) char(1) based(address);
27: dcl array2(1) char(1) based(address);
28:
29: address = addr(str);
30:
31: call foo(array1);
32: call foo(array2);
33:
34: end ProtoPli;
35:
36: end ProtoPliPackage;
37:
It compile with older compiler:
"IBM(R) PL/I for Windows 6.0"
"IBM(R) PL/I for Windows 7.5"
Compiler Version:
=> "IBM(R) PL/I for Windows 7.6"
Compiler output:
ProtoPli.pli(26:1) : IBM2209I S Use of nonconstant extents in BASED
variables without REFER is invalid except on scalars.
I can't use the glen's solution because i need descriptor info in my
procedure "foo"
kris
This isn't Fortran.
| Dimension it (1) and be sure SUBSCRIPTRANGE is disabled, at
| least for the statements that use it. Since there are no variables
| after it in the structure (well, no structure) then it won't
| cause any problems.
Really?
The array C_ARR is never allocated.
C_ARR is never initialized;
Furthermore, with a dimension of 1, as you suggest,
it follows that C_ARR can never be initialized with more than one element.
That's not the only problem that you have to resolve.
C_ARR is never allocated.
C_ARR is never initialized.
Therefore the code is nonsense.
Besides that, what's the point of using a based array?
Why not use an ordinary array?
C_ARR is allocated and initialized by the caller of this subroutine.
I don't use ordinary array because this subroutine runs for any array
of the caller.
kris
Yes. This isn't C, where you have to pass the address of the array.
Pass the array and the called code will know its bounds.
SWAP: PROCEDURE(C_ARR);
DECLARE C_ARR (*) CHAR(1);
DO I=LBOUND(C_ARR) TO HBOUND(C_ARR)-1 BY 2;
...
>C_ARR is allocated and initialized by the caller of this subroutine.
>I don't use ordinary array because this subroutine runs for any array
>of the caller.
Then what I suggested applies, namely, there is no point in using pointers at all.
An ordinary array will suffice.
And as the objects are characters, why not use a
character string instead of an array?
I know that it is not C.
From: Enterprise PL/I for z/OS: Enterprise PL/I Language Reference
"descriptor. A control block that holds information about a variable,
such as area size, array bounds, or string length."
In my example: descriptors are used...
I want to use descriptors.
With the old compiler all works but now with the new compiler i have a
severe message.
"IBM2209I S Use of nonconstant extents in BASED variables without
REFER is invalid except on scalars."
kris
No thanks
kris
> In my example: descriptors are used...
> I want to use descriptors.
>
You can call the variable you passed giving the upper bound of the array a
descriptor if you like but it isn't what the manual was referring to.
> With the old compiler all works but now with the new compiler i have a
> severe message.
> "IBM2209I S Use of nonconstant extents in BASED variables without
> REFER is invalid except on scalars."
>
All IBM PL/I compilers have required that string lengths, area sizes and array
bounds in based variables be constants. If a variable or expression is given
for a length, size, or bound then the REFER option must be specified and it
must refer to an element variable earlier in the structure. If your previous
compiler did not flag this error then the compiler had a bug.
> kris
>
>
>
>
>
>
>
>
>
>
>
>
It also contains the address.
>In my example: descriptors are used...
No you're not. You are using a pointer.
A pointer is an address. A pointer is not a descriptor.
>I want to use descriptors.
Then you must omit POINTER.
Your code if rewritten using descriptors takes about 9 lines of PL/I,
compared to your 18 lines.
Furthermore, code using descriptors is safe, whereas
yours isn't.
Peter has done all the re-writing you need
to use descriptors.
>With the old compiler all works but now with the new compiler i have a
>severe message.
>"IBM2209I S Use of nonconstant extents in BASED variables without
>REFER is invalid except on scalars."
That's because you are using a pointer,
whereas arrays as suggested by Peter are using descriptors.
There's really no point in using an array of single characters
because a string will enable groups to be identified and
extracted, searched, and manipulated.
My dimensions are not constant :(
My 2 source codes compile link and run on:
PL/I for Win* V1.R2.00, PL/I for Win* V1.R2.19, PL/I for Win*
V1.R2.38, PL/I for Win* V2.R0.00, PL/I for Win* V2.R0.01
PL/I for Win* V2.R1.00, PL/I for Win* V2.R1.04, PL/I for Win*
V2.R1.05, PL/I for Win* V2.R1.06, PL/I for Win* V2.R1.07
PL/I for Win* V2.R1.08, PL/I for Win* V2.R1.09, PL/I for Win*
V2.R1.10, PL/I for Win* V2.R1.11, PL/I for Win* V2.R1.12
PL/I for Win* 6.0, PL/I for Win* 7.5.
It's very strange, only PL/I for Win* 7.6 detect my fault ..?
Thanks robin, but they are only examples... (Useful to produce the
severe error)
I don't want that you improve my examples...
I don't want rewrite my real source codes ;)
kris
Your program is in error, and you need to rewrite it
in order to correct it.
We have suggested some ways in which that could be done.
At the same time, we have suggested using ways that are
not error prone like your code.
All the more reaosn to use what Peter suggested.
| My 2 source codes compile link and run on:
| PL/I for Win* V1.R2.00, PL/I for Win* V1.R2.19, PL/I for Win*
| V1.R2.38, PL/I for Win* V2.R0.00, PL/I for Win* V2.R0.01
| PL/I for Win* V2.R1.00, PL/I for Win* V2.R1.04, PL/I for Win*
| V2.R1.05, PL/I for Win* V2.R1.06, PL/I for Win* V2.R1.07
| PL/I for Win* V2.R1.08, PL/I for Win* V2.R1.09, PL/I for Win*
| V2.R1.10, PL/I for Win* V2.R1.11, PL/I for Win* V2.R1.12
| PL/I for Win* 6.0, PL/I for Win* 7.5.
|
| It's very strange, only PL/I for Win* 7.6 detect my fault ..?
Not strange. Not every error is detected by the compiler.
There's no requirement that a wrong program has to produce
a correct result.
And getting the correct answer doen't guarantee that the program is correct.