pascalopenvms

OpenVMS Pascal constant not constant when used as size initializer


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?


Solution

  • 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.