4

I think the easiest way of demonstrating the problem is with an example. The code:

PROGRAM CONSTANTSTRING(OUTPUT);

CONST
    C_MaxLength = 30;

VAR
    small_string : VARYING[5] OF CHAR VALUE 'alpha';

PROCEDURE LocalProc(
    localstring : VARYING[C_MaxLength] of CHAR
);
BEGIN
    writeln('localstring length: ', localstring.LENGTH);
    writeln('localstring size: ', SIZE(localstring.BODY));
    writeln('C_MaxLength: ', C_MaxLength);
END;

BEGIN
    writeln('small_string length: ', small_string.LENGTH);
    writeln('small_string size: ', SIZE(small_string.BODY));
    writeln('C_MaxLength: ', C_MaxLength);

    LocalProc(small_string);
END.

Compiling:

>pascal /version
HP Pascal I64 V6.1-116 on OpenVMS I64 V8.4
>pascal constantstringinit
>link constantstringinit
>run constantstringinit

And the output:

small_string length:          5
small_string size:          5
C_MaxLength:         30
localstring length:          5
localstring size:          5
C_MaxLength:          5

As you can see the value of C_MaxLength has changed locally inside the LocalProc procedure. Which is odd, since it has been declared a constant.

The new value of the constant is only within the scope of the LocalProc procedure. Code running in main after the call to LocalProc will use the original value of the constant.

At first this looked like a compiler bug to me, but I reasoned that this compiler has been around long enough that something like this would have been detected and either fixed or documented. But, I can't find any documentation on the matter. It doesn't help that VARYING is an HP extension, which means I can't compare to other Pascal implementations.

Do any gurus know more about what's going on here?

Dutch Gecko
  • 108
  • 1
  • 2
  • 9

1 Answers1

6

It's been a very long time and I can't find documentation to support it, but I think this is a special case of using varying[] of char as the type for a parameter:

    localstring : VARYING[C_MaxLength] of CHAR

This not only declares the parameter localstring but also a locally-scoped constant that receives the size of the actual string that's passed in. It's only because you named it the same as your global constant that causes the confusion. You haven't actually changed the value C_MaxLength. Instead you've got another C_MaxLength in the local scope.

Trying changing that line to something like:

    localstring : VARYING[foo] of CHAR

and then examine foo as well as C_MaxLength. I expect you'll see foo is 5 and C_MaxLength remains 30.

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
  • 2
    ISTM that you are right. The docs at http://h20565.www2.hpe.com/hpsc/doc/public/display?docId=emr_na-c04619807 say: "The upper-bound-identifier specifies the maximum length of the VARYING OF CHAR string and must denote an integer. The upper-bound-identifier that represents the maximum length can be thought of as a READONLY value parameter, implicitly declared in the procedure declaration." – Rudy Velthuis Jun 22 '17 at 21:52
  • Absolutely correct. Replacing with foo caused a new variable named foo to become available, and C_MaxLength was unaffected. Thank you to you both for the explanation and the doc link. P.S. for anyone reading this in the future, the relevant page of the PDF is 149 (numbered as 6-23). – Dutch Gecko Jun 23 '17 at 16:34