VAX PASCAL函数返回STRING类型编译报错问题求助
TYPCNTDISCR Error for String-Returning Functions Ah, classic VAX PASCAL quirk—this is a super common gotcha with how the language handles constrained types in function return values! Let's break down what's happening and how to fix it.
Why You're Seeing the TYPCNTDISCR Error
VAX PASCAL (and many older Pascal dialects from that era) doesn't allow functions to return discriminated types—types that carry extra runtime metadata, like the length constraint in STRING(16). The compiler can't handle storing and returning that discriminator (the 16 in your case) in the function return context, hence the error message: Type can not be discriminated in this context.
This is also why VARYING strings didn't work—they also store length metadata, making them discriminated types too.
Solutions to Get Your Code Working
Here are the three most common workarounds used in VAX PASCAL for this scenario:
1. Use an Unconstrained STRING Return Type
Instead of specifying a length for the function's return string, use the unconstrained STRING type. You can still use a constrained STRING(16) variable inside the function to build your result:
FUNCTION format(number : INTEGER) : STRING; VAR result : STRING(16); BEGIN { Your formatting logic here } format := result; { The constrained string will convert to unconstrained } END.
Just note that the caller will get a string with the actual length of your result (not padded to 16), so you may want to add explicit padding if needed.
2. Use a VAR Parameter (The Most Common VAX PASCAL Approach)
This is the pattern you'll see in almost all VAX PASCAL system examples (like those in SYS$EXAMPLES). Instead of returning the string, pass it in as a VAR parameter and modify it directly:
PROCEDURE format(number : INTEGER; VAR result : STRING(16)); BEGIN { Your formatting logic directly writes to the result variable } writeln(result); { If you still need to print it here } END.
This completely avoids the discriminated type return issue, and it's how most old-school Pascal code handled string output from procedures/functions.
3. Use a Packed Array (Manual Length Management)
If you absolutely must use a function return and need strict length control, you can define a packed array of chars instead. This is a non-discriminated type, so the compiler will accept it:
TYPE String16 = PACKED ARRAY[1..16] OF CHAR; FUNCTION format(number : INTEGER) : String16; VAR result : String16; i : INTEGER; BEGIN { Initialize the array to empty (e.g., fill with spaces) } FOR i := 1 TO 16 DO result[i] := ' '; { Your formatting logic here—write chars to specific positions in result } format := result; END.
The downside here is you have to manually manage the string's content and padding, since packed arrays don't have built-in length tracking like STRING types.
Final Note
VAX PASCAL's type system is very much a product of its time—constrained types were powerful for variables, but the compiler's function return mechanism couldn't handle the extra metadata they carried. The VAR parameter approach is by far the most idiomatic solution here, so that's what I'd recommend if you want your code to fit with standard VAX PASCAL practices.
内容的提问来源于stack exchange,提问作者Mike T.

