[an error occurred while processing this directive]

HP OpenVMS Systems

ask the wizard
Content starts here

Pascal and uninitialized variables?

» close window

The Question is:

 
Error when substr a variable declared
 
TmpStr : VARYING [12] OF CHAR;
 
In the previous releases of pascal if the variable contains 'ABCDEF' you used
 to be able to write
 
IF(INDEX(TmpStr[1..12],LookForStr)......
 
This goes for all subscr of the variables
But with 045 of pascal you cannot do this, you cannot access none initiated
 space, for the example above:
 
IF(INDEX(TmpStr[1..6],LookForStr)......
 
Can I somehow override this new behavior
 


The Answer is :

 
  The Pascal VARYING OF CHAR data type is specifically intended for
  manipulating variable-length strings.  The actual length of the
  string is maintained within the compiler, according to the history
  of the use of the variable.
 
  A reference to TmpStr[1..12] will be valid if and only if the current
  length of the string is greater than or equal to 12. By Pascal rules,
  if the string is shorter then you will receieve the SUBSTRSEL error.
  This is the correct, documented and expected behaviour.
 
  If this string reference were allowed in previous versions, then that
  would have been in error.  Perhaps the more recent compiler has been
  fixed to detect and report this?
 
  You can force the compiler to ignore various errors with the /CHECK
  qualifier.  In this case, with /CHECK=NOBOUNDS.  While this is quite
  feasible, the OpenVMS Wizard would strongly recommend against using
  this /CHECK approach here.
 
  Depending on exactly what you are trying to achieve and what semantic
  meaning(s) you assign to the data, there are several possibilities.
 
  First, if you really do want a fixed-length string, then don't declare
  it as VARYING.  Declare it as fixed-length:
 
    TmpStr : PACKED ARRAY [1..12] OF CHAR;
 
  The range 1..12 will then *always* be valid
 
  Second, why specify the bounds at all?  You could use the data type as
  it is intended and let the compiler supply the current length:
 
	IF(INDEX(TmpStr,LookForStr)....
 
  This will return "0" (ie: "not found") if TmpStr is currently null, or is
  shorter than the search string. This is presumably the correct behaviour.
 
  Another possibility here is to use one or both of the pseudo fields within
  the VARYING string data type - LENGTH and BODY. For example, you could
  conditionalise your statement depending on the current LENGTH of the
  string:
 
        IF TmpStr.LENGTH >= 12 THEN
 
  or, you could treat the string as a fixed 12 character string via the
  BODY field -- this particular approach is analogous to a data TYPE CAST,
  and can be equally dangerous:
 
	IF(INDEX(TmpStr.BODY[1..12],LookForStr)......
 
  In any case, the OpenVMS Wizard questions the correctness of any code
  which references uninitialised data, as the results will always be
  unpredictable.  Consider what would happen if the "junk" values just
  happened to match your search string?
 
  At the very least, you should initialise all varying strings to null.
 

answer written or last revised on ( 9-SEP-2002 )

» close window