[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