>> Strange behavior of substr ??? 
Author Message
 >> Strange behavior of substr ???


        >Glad this topic is still alive, because I can show an error  
        >that can occur using "varying" OR "varyingz" strings:

        >proc_name: proc;
        >dcl string_var char(32) varyingz;
        >dcl (i, j, k, l) fixed binary(31);

        >   do i = 0 to 5000 by 1000;

        >       do j = 0 to 319 by 32;
        >          string_var = "";   /* if varyingz */
        >          do k = 0 to 31 by 1;
        >              substr(string_var, k+1, 1) = substr(other_one,  j+k, 1);
        >          end;
        >       end;
        >   end;
        >end proc_name;

        >Okay, you get the idea...three loops and we're assigning values
        >to the VARYINGZ string (which was initialized to null length before
        >entering the 3rd loop).  Well, somewhere in the third loop, the
        >value of i and j will change.  We'll get a "memory violation"
        >or an "addressing exception" within the third loop, since it
        >references the value of j.

The problem with this code is that the variable "string_var"
is initialized to a null string.  It therefore has a length
of zero.

Such a string cannot be caused to "grow" by using the pseudo-
variable SUBSTR.  Thus, all references to "string_var" in
the innermost loop are in error, as there is no-where to
store characters.

The STRINGRANGE and STRINGSIZE considitions need
to be enabled, and the error will be detected on the first
execution of the innermost string assignment.

PL/I has great debugging facilities, and they might
be used as shown in the following code: [the code is the
above program segment with debug facilities added.]
_____________________________________________________________

(STRINGRANGE):
proc_name: proc;
        dcl string_var char(32) varyingz;

        dcl (i, j, k, l) fixed binary(31);

      on stringrange snap begin;
         put data (i, j, k);
         stop;
      end;

           do i = 0 to 5000 by 1000;

               do j = 0 to 319 by 32;
                  string_var = "";   /* if varyingz */
                  do k = 0 to 31 by 1;
                      substr(string_var, k+1, 1) = substr(other_one,  j+k, 1);
                  end;
               end;
           end;
end proc_name;
_____________________________________________________________________

When the code is run,the following messages are printed:

STRINGRANGE condition was raised
In source line 20 at offset +00000117 in procedure PROC_NAME
From source line 27 at offset +000000A5 in procedure TEST
I=             0        J=             0        K=              0;

=====================================================================
The inner loop is not efficient, BTW.  Better is to
replace the inner loop with a simple assignment:

string_var = substr(other_one, j, 32);  [or somesuch]

Then the problem all but disappears anyway, as the replacement
code is heaps safer.  (But you'll
still need to have STRINGSIZE and STRINGSIZE condition prefixes.)

        >Why?  Because, since i, j, and k are located near the string_var?
        >or, because the compiler just isn't smart enough to allocate
        >(i, j, k) values outside of the potential range of string_var?
        >or, becuase the compiler treats the do-loop's access of i,j,k as
        >stack frame references?

        >As character after character is moved from "other_ref" string
        >(maybe because it is being truncated on special char or something)
        >the result is that j counter counts  from 0, 1, 2, 3 to
        >12342345153 (or whatever "hex-char" || "000003"b4 equates to binary31)
        >on about the fourth time through the loop.

        >The correction is to assign "spaces" for the full length of
        >the dynamic string variable.
        >

        >>
        >> of course, those two bytes are an unsigned binary field (which limits
        >> length of the string to 64K) in the implementations I am aware of.
        >>


        >> > the problem is partly to do with the Varying string. If you assign 'xx' to
        >> > t, the rest of the string is NOT set to blank as in a fixed length> string.
        >> > There is a two-byte field in storage just before the 'actual' variable t
        >> > which contains it's length. This would be reset to '2'. Thus the storage
        >> > would look like this
        >> > Before:
        >> >       04abcd
        >> >
        >> > After:
        >> >       02xxcd



Sat, 15 Apr 2000 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Strange behavior of substr ???

2. HELP>>>>>>>Fortran-Pascal Linking

3. >>>>>>>FROM SMTK TO C++

4. ><><><><>Heeeeeeeeeeeeeeelp on INT 14!><><><><><>

5. <<<<<YOU MUST CHECK THIS OUT >>>>>>>>>> 2103

6. >>>>>AVL tree

7. >>>>>How to read a IMAGE file?(BMP, GIF)|||||||||

8. ANNOUNCE>>>>>TOTAL FrameWork from Cincom

9. Slow/No Speed>>>>>>>>>

10. Behavior>>new: comment

11. >>>>VHDL tutorial text: Summary >>>>

12. Graphics>>Rectangle>>intersects: erroneous code

 

 
Powered by phpBB® Forum Software