HP OpenVMS Systemsask the wizard |
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.
|