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

Ondrej Pokorny lazarus at kluug.net
Sat Jul 7 12:11:44 CEST 2018


On 07.07.2018 10:54, Florian Klämpfl wrote:
> Am 07.07.2018 um 08:18 schrieb Ondrej Pokorny:
>>
>> As you see, all messages are hints only, no warnings. Regardless of 
>> managed/not-managed global/local variable.
>>
>
> There are a lot of exceptions when which warning happens, try the same 
> with e.g. writeln and the file parameter (just one of these exceptions).

"A lot of exceptions" doesn't look like very systematic, logical and 
orthogonal in the first place.

> SetLength is a case were a warning is valid because it can result in 
> very bogus results (as this thread has shown).

I think you mean the "[fpc-devel] Managed Types, Undefined Bhaviour" thread.

"it can result in very bogus results" only in combination with the 
special Result function variable. Never with a local or global variable 
because they are guaranteed to be niled/zeroed (SetLength can be used on 
managed types only). Therefore the warning would make sense only in 
combination with function Result if your argument is used. With 
local/global variable the warning is not valid because it can NOT result 
in bogus results.

This applies to every other routine that takes a var parameter, not only 
SetLength. I don't understand why SetLength should be special. See the 
code below:

program Project1;
type
   Vector = array of integer;
procedure DoSetLength(var V: Vector; len: Integer);
begin
   SetLength(V, 4);
end;
function DoSomething1 (len: Integer): Vector;
begin
   DoSetLength(Result, len); // << HINT
end;
function DoSomething2 (len: Integer): Vector;
begin
   SetLength(Result, len); // << WARNING
end;
type
   TFoo = class
     A, B: Vector;
   end;
procedure Main;
var
   foo: TFoo;
begin
   foo := TFoo.Create;
   foo.A := DoSomething1(3); // try DoSomething2
   foo.A[0] := 42;
   foo.B := DoSomething1(4); // try DoSomething2
   Writeln(foo.B[0]);
end;
begin
   Main;
   Readln;
end.

Both DoSomething1 and DoSomething2 produce the same bogus code and yet 
you decided that DoSomething1 deserves a hint and DoSomething2 deserves 
a warning.

Earlier in this thread you wrote:

On 03.07.2018 20:54, Florian Klämpfl wrote:
> The warning happens also for any other call which takes an 
> uninitialized variable as var parameter (see e.g. fillchar). So the 
> warning increases only orthogonality of the language.

Which is not true because "any other call which takes an uninitialized 
variable as var parameter (see e.g. fillchar)" shows a hint only, not a 
warning:

procedure DoSomething;
var
   O, P: string;
begin
   SetLength(O, 1);   // << Warning
   FillChar(P, 1, 0); // << Hint
end;

I ask myself where is the orthogonality you wrote about?

On 07.07.2018 10:44, Florian Klämpfl wrote:
> Am 07.07.2018 um 08:05 schrieb Ondrej Pokorny:
>> makes me feel I have been always right in this thread...
>
> Fine, so we can close the case.

I agree. I officially stop trying to show you inconsistencies in your 
documentation and the compiler message system.

I find it ironic that you use arguments for the current state of 
documentation and compiler message system that - if you actually prove 
them - show exactly the inconsistencies I point to and are against the 
current state of documentation and compiler message system.

-----

Already in March/April this year I tried to convince the FPC team in 
this thread that the rules for warning/hint of initialized variables 
should be changed and that some warnings should be downgraded to notes. 
Jonas always replied with a disapproval.

Let me sum up my POV the last time:

throw a WARNING: if bogus results can happen.
throw a HINT: if bogus results can NOT happen.

You have then these 4 categories:
- uninitialized unmanaged+managed Result variable: bogus => WARNING
- uninitialized local unmanaged variable (ordinals etc): bogus => WARNING
- uninitialized local managed variable (strings etc): OK => NOTE
- uninitialized unmanaged+managed global variable: OK => NOTE

Especially you may not differentiate how the variable is used 
(right-side of the assignment, SetLength, other routine with var 
parameter etc.).

The current state is a strange mix of exceptions and rules that are 
irrational and not orthogonal.

To demonstrate my POV I made a small program that shows the current 
state and my POV:

program Project1;
uses StrUtils;
procedure DoVar(var S: string);
begin
   S := S + S;
end;
procedure DoVar(var O: Integer);
begin
   O := O + O;
end;
procedure Main;
var
   S1, S2, S3: string;
   O1, O2: string;
begin
   S1 := S1 + S1;             // << warning, should be: note    (WRONG)
   SetLength(S2, 0);          // << warning, should be: note    (WRONG)
   DoVar(S3);                 // << note,    should be: note    (OK)
   O1 := O1 + O1;             // << warning, should be: warning (OK)
   DoVar(O2);                 // << note,    should be: warning (WRONG)
end;
function M1: string;
begin
   Result := Result + Result; // << warning, should be: warning (OK)
end;
function M2: string;
begin
   SetLength(Result, 0);      // << warning, should be: warning (OK)
end;
function M3: string;
begin
   DoVar(Result);             // << note,    should be: warning (WRONG)
end;
function U1: Integer;
begin
   Result := Result + Result; // << warning, should be: warning (OK)
end;
function U2: Integer;
begin
   DoVar(Result);             // << note,    should be: warning (WRONG)
end;

var
   GS1, GS2, GS3: string;
   GO1, GO2: string;
begin
   GS1 := GS1 + GS1;          // << warning, should be: note    (WRONG)
   SetLength(GS2, 0);         // << warning, should be: note    (WRONG)
   DoVar(GS3);                // << note,    should be: note    (OK)
   GO1 := GO1 + GO1;          // << warning, should be: note    (WRONG)
   DoVar(GO2);                // << note,    should be: note    (OK)
end.

This should be the basis without any (additional) exceptions.

(The exceptions I wrote before like SetLength/FillChar being ignored for 
compiler messages etc. are still valid from the programmer's POV but 
don't have to be applied to keep the system simple and "orthogonal".)

Ondrej



More information about the fpc-devel mailing list