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

Ondrej Pokorny lazarus at kluug.net
Tue Jul 3 18:40:56 CEST 2018


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



More information about the fpc-devel mailing list