automatic PChar wrong for output param

Jay Michael <[email protected]>
Newsgroups gmane.comp.compilers.gpc
Message-ID <[email protected]>
gpc 20070904, based on gcc-3.4.5 (mingw special)

If an array of CHAR is used as the actual argument for
a formal parameter declared as "x : PChar", a temporary
STRING object is created, the actual argument is copied
to the temporary, and the address of the temporary is
passed to the subroutine.

     This is no good when the parameter is a pointer to
an output buffer.

     Using "@s[1]" as the actual argument passes the 
right address, but if "s" is a STRING, the index "1" is
checked, resulting in a RangeCheckError unless the STRING
is initialized.
     I've accepted having to "SetLength" before reading or
writing individual characters of the STRING.  I didn't
expect referring to a character of the STRING in order to
get its address to be considered an "access" that would 
trigger a Range Check.  (I planned to set the length of
the STRING after the subroutine told me how many characters
it had written to the buffer.)

_______________________________________________
Gpc mailing list
[email protected]
https://www.g-n-u.de/mailman/listinfo/gpc
jsm4.pas (text/plain, 1 KB)
{ Automatic conversion of "array of CHAR" to PChar           }
{ is accompanied by making a copy of the specified argument. }
{ This is unsuitable for an output parameter -- the returned }
{ value is lost.                                             }

{ "@s[1]" produces an address, but triggers range checking   }
{ when "s" is a STRING, so "s" needs to be initialized       }
{ before it can be passed to a procedure that won't pay any  }
{ attention to its initial value.                            }

program JSM3( INPUT, OUTPUT ) ;

var
  CARR : array [ 1 .. 8 ] of CHAR ;
  STR : STRING( 6 ) ;

procedure SET_SOME( BUF : PChar ) ;
  var
    P : PChar ;
  begin
  P := BUF ;
  P^ := 'O' ;
  P := PChar( PtrCard( P ) + 1 ) ;
  P^ := 'K' ;
  end ;

begin
CARR := 'FAIL' ;
WRITELN( CARR, ' before SET_SOME' ) ;
SET_SOME( CARR ) ;
WRITELN( CARR, ' after  SET_SOME' ) ;

SET_SOME( @STR[1] ) ; { RangeCheckError unless Length happens to be good }
SetLength( STR, 2 ) ;
WRITELN( STR, ' after  SET_SOME' ) ;
end.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.