gm2
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]