[fpc-devel] (not) initialized managed variable / regarding ansistring

Martin Frb lazarus at mfriebe.de
Sun Feb 23 20:42:28 CET 2025


Ok, so we all (should?) know

function Foo: ansistring;
var s: ansistring;
begin
   SetLenght(s, 10000); fillchar(@s[1], 10000, ' ');
   SetLenght(Result, 10000); fillchar(@Result[1], 10000, ' ');
end;

This will give the "uninitialized" warnings, as SetLength takes a "var 
param".

However, despite the warning this is valid code. Whatever the string 
contains, the result will be as expected.
The combination of SetLength and fillchar (or any means to fill the 
content) will initialize the string.

I will still, to make sure ask:  Is the above statement correct?

However I realized, it may not be optimal. At least not for strings.

Internally both strings must be initialized, even before the SetLength. 
Initialized in the sense that the EITHER
- are nil
- point to a refcounted string-content
If they would not be, then even initializing with
   s := ''; result := '';
would not work, because those statement also require the strings to be 
initialized (as they will call fpc_ansi_string_dec_ref).

But of course it is not guaranteed by documentation that this 
"initialized value" of the strings would be nil. (empty string).

So in the original example above, if either string is having a large 
content (pointing to a length = 1MB chars area), then SetLengh would 
copy "10000" chars of that into the new unique string.
Such a copy would be an unnecessary cost.

I know this will happen (with smaller length) when using -gt.
But will it ever happen in any other case?

I guess for "Result" the answer will be, yes that can happen, as a temp 
variable is passed in.

What about the local var "s"? Other than -gt, can that really happen?

-------------------
As a side note

program Project1;
procedure foo;
var
   s: ansistring;
begin
   SetLength(s, 100);
end;

begin
   foo;
end.

Compile with -O3 and somehow the compiler realizes that s is 
initialized. The warning is gone.

Interestingly -O3 will also do that for "result" in "function foo: 
ansistring;" => Doesn't that depend on the caller, or is there some magic?


More information about the fpc-devel mailing list