[fpc-devel] Wrong docs: not initialized global variables

Stefan Glienke sglienke at dsharp.org
Tue Jul 3 19:53:23 CEST 2018


SetLength should not cause anything uninitialized.

It enlarges or shrinks the data and keeps any prior data as it was, new allocated memory is zeroed (at least that is how it works in the Delphi RTL and I would be very surprised if FPC would do any different).

The core issue imo is temp var reuse the compiler does which causes hidden data reusage/copy which is only an issue with dynamic arrays because they don't have CoW semantic when writing to some index. So the temp variable still points to the first array which then gets passed to the next function as result. There a call to SetLength applies copy on write semantics carrying over any content from the previous array that is still in the temp variable to the newly allocated array.

I think we discussed this on friday - maybe I did not make my point clear enough.

> On 03 July 2018 at 18:40 Ondrej Pokorny <lazarus at kluug.net> wrote:
> 
> 
> On 04.04.2018 21:51, Jonas Maebe wrote:
> > On 04/04/18 20:26, Ondrej Pokorny wrote:
> >> The compiler initializes the variable implicitely for myself - this 
> >> is documented and I know it. There cannot be "wrong code behaviour" 
> >> (as you stated) and thus I cannot have an error. This is simple logic.
> >
> > "Wrong behaviour" is not the same as "undefined behaviour" or "crash". 
> > It merely means "something different than the programmer intended". It 
> > is of course possible that you wanted the behaviour that you get when 
> > the variable contains the empty string, nil or 0, but because this 
> > initialisation is implicit rather than explicit, the compiler does not 
> > rely on this. After all, it is equally possible that you forgot to 
> > assign the correct (non-nil/0/empty string) value to the variable 
> > before using it the first time (in which case it would be an error in 
> > the program).
> >
> >> I must not. Turning off warnings is forbidden. Turning off hints and 
> >> notes is OK. That is the rules. 
> >
> > The inflexibility of that rule in the Lazarus project is not a good 
> > reason to change the priority of the message.
> >
> >> But I am not fine with the fact that the level of this message is a 
> >> WARNING - the same level that real code errors are reported. 
> >
> > Warnings are not errors. Warnings indicate possible errors, but they 
> > can also be false positives.
> 
> The recent change in SetLength emitting an "uninitialized variable" 
> error is a 100% false positive, completely useless and produces only 
> garbage in compiler output.
> 
> Reasons:
> 
> 1.) SetLength itself produces an unitialized block of data within the 
> variable if the new length is bigger than the old length.
> 
> Therefore it would be more appropriate to get an "uninitialized warning" 
> after SetLength:
> 
> program Project1;
> var
>    S: string;
> begin
>    SetLength(S, 10); // <<< warning here     --->> WHY ????
>    Writeln(S[2]);    // <<< no warning here  --->> WHY ????
> end.
> 
> 2.) If the variable was uninitialized before SetLength it will be 
> uninitialized after SetLength as well, regardless if the new length if 
> bigger or smaller.
> 
> 3.) The old data is not really read or used anyhow. It is just copied on 
> raw-basis.
> 
> 4.) I use "SetLength(A, 0);" to explicitely initialize an array. The 
> compiler warns me now that A is not initialized. Seriously?
> I know that with a recent FPC version I can use:
> 
> program Project1;
> var
>    A: array of Integer;
> begin
>    A := [];
> end.
> 
> or
> 
> program Project1;
> type
>    IntArray = array of Integer;
> var
>    A: IntArray;
> begin
>    A := Default(IntArray);
> end.
> 
> but using "SetLength(A, 0)" is the old way to do it:
> 
> program Project1;
> var
>    A: array of Integer;
> begin
>    SetLength(A, 0); // <<< warning here     --->> WHY ????
> end.
> 
> 5.) If you really want to handle SetLength, then SetLength should be a 
> trigger for the warning detection in subsequent code (warnings should 
> appear after SetLength):
> 
> program Project1;
> var
>    S: array of string;
> begin
>    S := [];
>    SetLength(S, 10);
>    Writeln(S[2]);    // <<< no warning here  --->> WHY ????
> end.
> 
> ---
> 
> All in all, there should not be a warning in SetLength at all. Because 
> SetLength is a compiler intrinsic with well-defined and documented 
> behavior I am sure it can be handled as I described (desired = no 
> warning at SetLength, but warning afterwards).
> 
> Ondrej
> _______________________________________________
> fpc-devel maillist  -  fpc-devel at lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



More information about the fpc-devel mailing list