New GPC beta: gpc-971001_(re)
Fri, 10 Oct 1997 09:44:04 +0100 (BST)
On Fri, 10 Oct 1997 00:21:00 +0200 Frank Heckenbach
wrote:
>
>The African Chief wrote:
>
>> However, I fail to see the problem with Str2pChar. It works correctly in
>> all my tests (at least, under BP7, BPW, Delphi 1 and Delphi 2).
>
>...which is a nice example for the fact that testing alone doesn't prove
>correctness... ;-)
You are right here!
>
>First of all, there is a problem if s has full length, and "s+Chr(0)" would
>overflow s. Currently this is not noted (a bug in GPC), but when the bug is
>fixed, it will either trigger a runtime error or cut the result, i.e. not
>append the #0.
True :-(
>
>In BP (which doesn't have this bug and always cuts strings), the routine
>indeed behaves wrong is this situation. See the following program:
>
>program x;
>
>Function Str2pChar ( Var s : String ) : pChar;
>Var
>x : String;
>Begin
> x := s;
> s := s + Chr ( 0 );
> Str2pChar := @s [1];
> s := x;
>End; {* str2pChar *}
>
>const
> s:string=' '+
> ' '+
> ' '+
> ' '+
> ' '#13#10'This program is OK.';
> t:string=#8#8#8#8'wrong, sorry.'#0;
>
>var p:pchar;
>
>begin
> p:=str2pchar(s);
> writeln(p);
>end.
Yes, the program shows the bug :-(
>
>Secondly, you copy back the old value of s back afterwards. This only works
>because GPC copies only Length(x) characters. If this behaviour would be
>changed to copy more characters (of course not more than x.Capacity), your
>code would break. (Such a change might be done for efficiency, e.g. by
>rounding up to a multiple of 4, and though I don't think it's likely to
>be changed, the change would be valid,
I disagree that it would be valid.
>AFAIK, since the characters after Length(x) in a string are undefined.)
Which is why you should only copy to length(s).
If I do "str1 := str2" , I do not expect an optimiser to make it into;
"str1 := str2 + any junk after the length of str2, up till str2.capacity".
>
>A possible "fix" for the second problem (not the first one, though the
>appearance of the problem will be different then) would be
>"s[Length(s)+1]:=#0" (also, it's much more efficient).
I am not sure how this solves the problem.
>But don't worry too much about these functions. Sooner or later, such
>functionality will be built-in into GPC...
That will be good. The compiler can better cater for some things. However,
I have a version of Str2pChar which deals with this bug, but it would require
the user to dispose of memory afterwards - which means it cannot be used
in an expression (which is what I want it for). I have added this version to
system.pas, but commented it out. I have also noted the "full length string bug"
in the sources. This is the fixed version, which seems to work okay. Any
comments?
program x;
uses
strings;
Function Str2pChar ( s : String ) : pChar;
Begin
Str2pChar := StrNew ( StrCopy ( @s [1], @s[1] ) );
End; {* str2pChar *}
const
s:string=' '+
' '+
' '+
' '+
' '#13#10'This program is OK.';
t:string=#8#8#8#8' wrong, sorry.'#0;
var
p:pchar;
begin
p:=str2pchar(s);
writeln(p);
StrDispose(p); { need to dispose of the memory! }
end.
BTW:
"const t:string=#8#8#8#8' wrong, sorry.'#0;" doesn't compile
under GPC !
Best regards, The Chief
Dr Abimbola A. Olowofoyeku (The African Chief, and the Great Elephant)
Author of: Chief's Installer Pro v4.01 for Win16 and Win32.
Homepage: http://ourworld.compuserve.com/homepages/African_Chief/
E-mail: laa12@keele.ac.uk
The African Chief (laa12@cc.keele.ac.uk)
HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada -
Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es