delphicompiler-errorsdelphi-11-alexandria

Why does the Delphi compiler think that the value of a local boolean variable is initialized when it obviously is not?


Documentation: 1, 2:

USE_BEFORE_DEF W1036
W1036 Variable '%s' might not have been initialized (Delphi)
This warning is given if a variable has not been assigned a value on every code path leading to a point where it is used.

I have the following code in an empty form:

{$WARN USE_BEFORE_DEF ERROR}
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  lHandled: Boolean;
begin
  // Using this block shows no warnings no errors!
  if False then
    OnMouseWheelUp(Self, [], Point(0,0), lHandled);

  // Using this block shows the E1036 error (as expected)!
  //if False then
  //  lHandled := True;

  if lHandled then
    Memo1.Lines.Add('Handled = true') // depending on the chance, one of these branches will be chosen
  else
    Memo1.Lines.Add('Handled = false'); // depending on the chance, one of these branches will be chosen
end;

Obviously, lHandled can have no value assigned (since there is no else branch). However, even despite the {$WARN USE_BEFORE_DEF ERROR} the code is assembled without any warnings or errors. Why doesn't the compiler see that the variable is potentially not initialized? Is it a bug or a known "feature"?


Solution

  • Delphi's warning in regard to variable initialization has been unreliable (or even non existant?) for a long while when passing said variable by reference (including as const [ref]) to another function.

    You don't even need a branch to break it. This still won't give a warning (as of Delphi 11.3) while it definitely should :

    procedure TForm1.FormCreate(Sender: TObject);
    var obj : TObject;
    begin
      Obj.Free;
      FreeAndNil(Obj);
    end;
    

    But this will

    procedure TForm1.FormCreate(Sender: TObject);
    var obj : TObject;
    begin
      Obj.Free;
    end;
    

    So yeah, I'd call it bugged.