[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Inconsistent HIGH values with 'ARRAY OF CHAR'
From: |
Gaius Mulley |
Subject: |
Re: Inconsistent HIGH values with 'ARRAY OF CHAR' |
Date: |
Wed, 24 May 2023 12:16:24 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) |
Rudolf Schubert <rudolf@muc.de> writes:
> One thing I noted today is:
>
> the HIGH values seen inside a PROCEDURE do not reflect the expectations.
>
> Again, I've written a small example program which shows the problem:
>
>
> MODULE port_test8_gm2;
>
> FROM IOChan IMPORT
> ChanId;
> FROM StdChans IMPORT
> StdOutChan;
> FROM Strings IMPORT
> Length;
> FROM TextIO IMPORT
> WriteLn, WriteString;
> FROM WholeIO IMPORT
> WriteCard;
>
>
> VAR
> str_a: ARRAY[0..0] OF CHAR;
> str_b: ARRAY[0..1] OF CHAR;
> str_c: ARRAY[0..2] OF CHAR;
>
>
> PROCEDURE ShowStringInfos(the_str: ARRAY OF CHAR);
> VAR
> cid_out: ChanId;
>
> BEGIN (* PROCEDURE ShowStringInfos *)
> cid_out:=StdOutChan();
>
> WriteString(cid_out, 'Length(the_str): ');
> WriteCard(cid_out, Length(the_str), 1);
> WriteLn(cid_out);
>
> WriteString(cid_out, 'HIGH(the_str): ');
> WriteCard(cid_out, HIGH(the_str), 1);
> WriteLn(cid_out);
>
> WriteString(cid_out, 'the_str: ');
> WriteString(cid_out, the_str);
> WriteLn(cid_out);
>
> WriteLn(cid_out);
> END ShowStringInfos;
>
>
> BEGIN (* MODULE port_test8_gm2 *)
> ShowStringInfos('1');
> ShowStringInfos('12');
> ShowStringInfos('123');
>
> str_a:='a';
> ShowStringInfos(str_a);
> str_b:='ab';
> ShowStringInfos(str_b);
> str_c:='abc';
> ShowStringInfos(str_c);
>
> str_c:='d';
> ShowStringInfos(str_c);
> END port_test8_gm2.
>
>
> ShowStringInfos just prints out the Length, the HIGH value and the
> string proper which is passed to the PROCEDURE. When using literals
> '1', '12' and '123' the HIGH values are 0, 2 and 3. So I guess either
> for '1' the HIGH value should be 1 and not 0 or for '12' and '123'
> the HIGH values should be 1 and 2 and not 2 and 3. I can only compare
> with GPM and there they report a HIGH value of 1 for '1' (and 2 and 3
> for '12' and '123'). So the question is what will be the correct behaviour?
Hi Rudolf,
many thanks for the bug report - all fixed in the latest git. I've
added a new section in the documentation and also regression testcode
for the following table,
regards,
Gaius
------------------------------------------------------------------------
@section Behavior of the high procedure function
This section describes the behavior of the standard procedure function
@code{HIGH} and it includes a table of parameters with the expected
return result. The standard procedure function will return the last
accessible indice of an @code{ARRAY}. If the parameter to @code{HIGH}
is a static array then the result will be a @code{CARDINAL} value
matching the upper bound in the @code{ARRAY} declaration.
The section also describes the behavior of a string literal actual
parameter and how it relates to @code{HIGH}.
The PIM2, PIM3, PIM4 and ISO standard is silent on the issue of
whether a @code{nul} is present in an @code{ARRAY} @code{OF}
@code{CHAR} actual parameter.
If the first parameter to @code{HIGH} is an unbounded @code{ARRAY} the
return value from @code{HIGH} will be the last accessible element in
the array. If a constant string literal is passed as an actual
parameter then it will be @code{nul} terminated. The table and
example code below describe the effect of passing an actual parameter
and the expected @code{HIGH} value.
@example
MODULE example1 ;
PROCEDURE test (a: ARRAY OF CHAR) ;
VAR
x: CARDINAL ;
BEGIN
x := HIGH (a) ;
...
END test ;
BEGIN
test ('') ;
test ('1') ;
test ('12') ;
test ('123') ;
END example1.
Actual parameter | HIGH (a) | a[HIGH (a)] = nul
===============================================
'' | 0 | TRUE
'1' | 1 | TRUE
'12' | 2 | TRUE
'123' | 3 | TRUE
@end example
A constant string literal will be passed to an @code{ARRAY} @code{OF}
@code{CHAR} with an appended @code{nul} @code{CHAR}. Thus if the
constant string literal @code{''} is passed as an actual parameter (in
example1) then the result from @code{HIGH(a)} will be @code{0}.
@example
MODULE example2 ;
PROCEDURE test (a: ARRAY OF CHAR) ;
VAR
x: CARDINAL ;
BEGIN
x := HIGH (a) ;
...
END test ;
VAR
str0: ARRAY [0..0] OF CHAR ;
str1: ARRAY [0..1] OF CHAR ;
str2: ARRAY [0..2] OF CHAR ;
str3: ARRAY [0..3] OF CHAR ;
BEGIN
str0 := 'a' ; (* No room for the nul terminator. *)
test (str0) ;
str1 := 'ab' ; (* No room for the nul terminator. *)
test (str1) ;
str2 := 'ab' ; (* Terminated with a nul. *)
test (str2) ;
str2 := 'abc' ; (* Terminated with a nul. *)
test (str3) ;
END example2.
Actual parameter | HIGH (a) | a[HIGH (a)] = nul
===============================================
str0 | 0 | FALSE
str1 | 1 | FALSE
atr2 | 2 | TRUE
str3 | 3 | TRUE
@end example