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.