On Fri, 10 Oct 1997 00:21:00 +0200 Frank Heckenbach heckenb@mi.uni-erlangen.de 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