Recent

Author Topic: NewStr/AssignStr dont conform to Delphi standard  (Read 783 times)

dje

  • Full Member
  • ***
  • Posts: 134
NewStr/AssignStr dont conform to Delphi standard
« on: December 10, 2022, 09:46:56 am »
Delphi's NewStr returns a valid pointer for empty strings. FreePascal returns nil.
Code: Pascal  [Select][+][-]
  1. S := NewStr('')

Delphi's AssignStr accepts nil and allocates new memory. FreePascal throws an "Access violation" on nil.
Code: Pascal  [Select][+][-]
  1. AssignStr(S, 'New String');

Effectively it means NewStr('')'s must be replaced with at lease a space, or the following code.
Code: Pascal  [Select][+][-]
  1.     P := NewStr(' ');
  2.     AssignStr(P, '');  

Since empty strings return a nil, all code which de-references empty strings must check for nil before doing so.

Tested against Delphi 11 and FPC 3.2.2
« Last Edit: December 10, 2022, 09:50:37 am by dje »

dje

  • Full Member
  • ***
  • Posts: 134
Re: NewStr/AssignStr dont conform to Delphi standard
« Reply #1 on: December 10, 2022, 09:52:38 am »
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2.  
  3. program StrTest;
  4.  
  5. uses
  6.   SysUtils;
  7.  
  8. var
  9.   P: PString;
  10.  
  11. begin
  12.   try
  13.     P := NewStr(''); // Replace with space to make it work
  14.     AssignStr(P, 'This will crash');
  15.     Writeln('Before: P = "', P^, '"');
  16.     AssignStr(P, 'A Second ansistring');
  17.     Writeln('After : P = "', P^, '"');
  18.     DisposeStr(P);
  19.   except
  20.     on E: Exception do WriteLn(E.Message);
  21.   end;
  22.   ReadLn;
  23. end.

dje

  • Full Member
  • ***
  • Posts: 134
Re: NewStr/AssignStr dont conform to Delphi standard
« Reply #2 on: December 10, 2022, 10:49:20 am »
Just an update: It would appear GetStr/DisposeStr originate from TP7 via the "Objects" unit.
TP7 also returns nil for GetStr('') but doesn't contain a AssignStr function.

I checked the FreePascals Object unit, and the documentation is clear:
Quote
If the string is empty then Nil is returned.
https://www.freepascal.org/docs-html/rtl/objects/newstr.html

But, it then contains the procedure SetStr which does accept a nil, so this code doesn't crash:
Code: Pascal  [Select][+][-]
  1. {$mode delphi}
  2. program StrTest;
  3. uses SysUtils, Objects;
  4. var P: PString;
  5. begin
  6.   try
  7.     P := NewStr('');
  8.     SetStr(P, 'This now wont crash');
  9.     Writeln('Before: P = "', P^, '"');
  10.     SetStr(P, 'A Second ansistring');
  11.     Writeln('After : P = "', P^, '"');
  12.     DisposeStr(P);
  13.   except
  14.     on E: Exception do WriteLn(E.Message);
  15.   end;
  16.   ReadLn;
  17. end.  

I guess the 3 GetStr/AssignStr/DisposeStr functions in SysUtils could be removed if they arn't going to be updated.
The Objects unit is enough for legacy code.
 

nanobit

  • Full Member
  • ***
  • Posts: 160
Re: NewStr/AssignStr dont conform to Delphi standard
« Reply #3 on: December 10, 2022, 09:38:21 pm »
If functions need more nil checks, you could report them in the bug tracker.

NewStr('') returning nil (but in Delphi: global NullStr) could be seen as preferable:
Spreading the NullStr (PString) via pointer variables is risky because they should be used only for read access, whereas write access (p^:= s;) would change the global NullStr.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11446
  • FPC developer.
Re: NewStr/AssignStr dont conform to Delphi standard
« Reply #4 on: December 10, 2022, 10:02:49 pm »
The sysutils ones are probably for backwards compatibility with 16-bit Delphi 1, and should be treated separate from unit objects.

Please file a bug with a reproduction case.

 

TinyPortal © 2005-2018