PL/I

PL/I

PL/I

 View Only
Expand all | Collapse all

CHAR strings as DO control-variable and TO expression

  • 1.  CHAR strings as DO control-variable and TO expression

    Posted Fri August 02, 2019 04:46 PM

    In my reading of the PL/I standards, the control-variable of a DO loop is required to be compuatational,which allows for it to be a CHAR string.

    Furthermore, the terminating "TO" value has to be converted to the common arithmetic derived type between the control-variable and the TO expression.

    If both the control-variable and the TO expression are CHAR strings, then wouldn't the common arithmetic type be a FIXED DECIMAL(31,0)?

    That is, the test for loop termination should be done between two FIXED DECIMAL values, not a CHAR string comparison.  The TO value would be converted to the common-derived (arithmetic) type and saved at the start of the loop.  The termination test would then be obliged to convert the control-variable to the common arithmetic type for the comparison.

    If I'm reading that from the standard correctly, then this code should terminate - but it gets an infinite loop - am I mis-understanding something?

     

     test: proc options(main);

     

      innerdo: proc(len1, len2);

       dcl (len1, len2) fixed bin(31);

       dcl ch char(len2);

       dcl idx char(len1);

     

       ch = 10;

     

       do idx = 1 to ch;

        display('idx is "' || idx || '"');

       end;

     

       return;

      end;

     

      call innerdo(50, 10);

     

     end;

     

      - Thanks -

     

     

     

     

    tdr


  • 2.  Re: CHAR strings as DO control-variable and TO expression

    Posted Tue August 06, 2019 01:43 PM

    The compiler is generating correct code: at the end of each iteration of the loop, IDX is converted to FIXED DEC(31), one is added to that, and the result is converted back to IDX. Then IDX is compared to CH, but that is a character compare and since CH = '    10' (the result of converting the FIXED DEC(2) value 10 to CHAR) while IDX = '               nn' (the result of converting a FIXED DEC(31) value to CHAR), IXD is less than CH and the loop continues.

     

    When using TO or BY, the loop control variable should almost always be numeric (and probably best as FIXED BIN). Perhaps an RFE should be opened so that the compiler would flag when this wasn't true?

    pelderon


  • 3.  Re: CHAR strings as DO control-variable and TO expression

    Posted Tue August 06, 2019 02:18 PM

    Hi Peter!

     

      Thanks for taking the time to respond to my post.

     

      But, in my reading of the PL/I standard(s) (both seem to be pretty much the same in this area), the value of the TO expression would be calculated then saved in the common arithmetic derived type.   Thus, the comparison between IDX and the TO expression would be directly to the CHAR STRING CH, but to the saved arithmetic value (in this case, FIXED BIN).

       

      So (I think?) the comparison between IDX should be that IDX is converted to a FIXED BIN, and that FIXED BIN would be compared with the previously saved FIXED BIN that results from the original conversion of CH...

     

      That is, it shouldn't be a character comparison, and since the common derived type would be FIXED BIN, it shouldn't be FIXED DEC.

     

      Unless I'm reading the standard wrong somewhere???

     

         - Thanks -

     

    tdr


  • 4.  Re: CHAR strings as DO control-variable and TO expression

    Posted Tue August 06, 2019 03:34 PM

    Hi again,

     

    in the LRM description, we say

     

          If the TO option is present, test the value of the control variable against the previously-evaluated expression (E2) in the TO option.

     

    it does not specify if this comparison should be based on a common type or a common numeric type, but the OS PL/I compiler and PL/I for MVS compiler made the same choice as Enterprise PL/I: the comparison is done based on the common type of the 2 comparands (as is the case for all other comparisons) and hence a string compare is made

     

    this may differ from the standard, but it is what our compiler has done for many years, and I would be loathe to change it and possibly break some code

     

    But I am also curious why anyone would write such a loop. All the conversions required will make it perform badly and exactly what will happen is probably unclear to many

    pelderon


  • 5.  Re: CHAR strings as DO control-variable and TO expression

    Posted Tue August 06, 2019 04:33 PM

    Thanks so much for your reply!

     

     You're right of course, this is a silly loop - I'm trying to understand the semantics here which is what led me to the PL/I standard(s).   The LRM says "previously saved" value and doesn't describe the type of the previously saved value, but I see it converting a BY expression (similar to TO) to arithmetic and not doing the same for TO.   And, as you mention, it seems to be copying (when needed) the TO expression to a temporary.

     

     But - let's consider this slightly different loop.... in the generated code it does copy the return value from the function call to VAL, and it does a fixed-len character comparison between IDX and this saved value (a CLC)... but the loop doesn't end anyway...

     

      If I'm following things correct; at the end of the loop, the value of IDX would be converted to FIXED DEC, a 1 is added (since the BY value is an implied FIXED DEC 1) and that value would be converted back to CHAR(50) for storing to IDX.  This value would then be compared with the previously saved value.

     

      Since VAL returns a CHAR 50 that is also the conversion of a FIXED DEC value (either 10 or 5 - which is done to demonstrate that VAL is only invoked once), the first call to VAL would return a CHAR(50) that is the conversion of 10 to a CHAR(50).  Evemtually, the value of IDX should be the same FIXED DEC 10 converted to CHAR(50). 

     

      Since both sides of the comparison are conversions of FIXED DEC to CHAR(50) - wouldn't this end the loop?   Why is this one infinite?

     

     test: proc options(main);

     

       dcl flag fixed bin(31);

       dcl idx char(50);

     

       val: proc returns(char(50));

         if(flag = 0) then return (10);

         else do;

          flag = 1;

          return (5);

         end;

      end;

     

       flag = 0;

       do idx = 1 to val();

          display('idx is ' || idx);

       end;

     end;

     

     

    Perhaps these issues are why the standard converts the TO expression to an arithmetic value instead of leaving it as CHAR for the comparison?  (Certainly saving an arithmetic value is a lot easier than a CHAR temporary.)

     

    But - in either case - I don't think the loop should be infinite in this 2nd example... no?? (Maybe I'm missing something else?)   

    tdr


  • 6.  Re: CHAR strings as DO control-variable and TO expression

    Posted Tue August 06, 2019 05:44 PM

    This new variant behaves as follows

    1 is assigned to IDX ; so this converts a DEC(1,0) to CHAR and results in IDX being 3 blanks followed by '1' and a bunch of blanks

    VAL is invoked and returns 10 converted to CHAR; so VAL returns a string of 3 blanks followed by '10' and more blanks

     'bbb1' is not greater than 'bbb10' so the loop starts

    at the end of the loop, IDX is assigned the DEC(31,0) value of 2 (etc) and becomes a lot of blanks followed by '2' ( or '3' etc)

    IDX is still not greater than 'bbb10' and the loop goes on.

     

    This variant would avoid the problems of the differing source precisions in the various conversions to CHAR:

     

     test: proc options(main);

       dcl flag fixed bin(31);
       dcl idx char(50);

       val: proc returns(char(50));

         if (flag = 0) then do;
           return ( fixeddec(10,31) );
         end;
         else do;
           flag = 1;
           return ( fixeddec(5,31));
         end;
      end;

       dcl jx fixed bin init(1);

       flag = 0;

       do idx = fixeddec(1,31) to val();
         display('idx is ' || idx);
         jx += 1;
         if jx > 15 then stop;

       end;

     end;   

     

     

    pelderon


  • 7.  Re: CHAR strings as DO control-variable and TO expression

    Posted Tue August 06, 2019 07:54 PM

    Ah - the DEC(31,0) because of the calculation changes things for sure (different spaces!)

     

    Because - it will still loop forever if you reverse the values returned by the VAL function.

     

    That all makes sense - except for IBM's deviation from the PL/I standard(s), which as you say, is not something that would be prudent to address at this point.

     

    So - what if the compiler cannot determine the length of the string temporary at compile-time - is it then obligated to create an "as large is is possible" string temporary?

    tdr


  • 8.  Re: CHAR strings as DO control-variable and TO expression

    Posted Tue August 06, 2019 07:54 PM

    Oh - and I should say again - many many thanks for taking the time to lay this all out!

    tdr


  • 9.  Re: CHAR strings as DO control-variable and TO expression

    Posted Wed August 07, 2019 11:56 AM

    You asked: So - what if the compiler cannot determine the length of the string temporary at compile-time ...

    in these loops, the compiler would know the length of the string temporary because it would be the result of converting a FIXED DEC(p,0) to CHAR and that always has length (p+3)

    pelderon


  • 10.  Re: CHAR strings as DO control-variable and TO expression

    Posted Wed August 07, 2019 02:02 PM

    I was thinking about the length of the TO expression - as in:

     

       do_loop: proc(to_expr);

          dcl to_expr char(*) varying;

     

          do idx = 1 to to_expr;

            display('idx is ' || idx);

            to_expr = 10;

          end;

     

          return;

       end;

     

     

    It looks like, in this instance, the compiler is obliged to allocate the largest allowable fixed-len CHAR for the temporary (looking at the generated code) since it can't know the length at compile time.  So the area allocated for the DSA is a little large in this instance... but, there's not much else that can be done, I think...

    tdr


  • 11.  Re: CHAR strings as DO control-variable and TO expression

    Posted Wed August 07, 2019 02:29 PM

    yes, in this case, a big temp would be allocated

    pelderon