缺少有关变量的警告可能尚未初始化

Missing warning about variable might not have initialized

我的代码中有一个错误。毫无疑问。这是我的错误,完全是我的错:

procedure TfrmCageSetup.actDeleteFloatExecute(Sender: TObject);
var
   conn: TADOConnection;
begin
   ...
   if not float.CanDelete(conn, {out}noDeleteReason) then
   begin
   ...
end;

我忘了初始化变量conn。结果,它是堆栈垃圾。当目标被调用者检查参数时,它通过:

function TFloat.CanDelete(Connection: TADOConnection; out NoDeleteReason: string): Boolean;
begin
   if Connection = nil then
      raise EArgumentNullException.Create('Connection');

我有时会遇到非常奇怪的访问冲突。

但为什么 Delphi 没有抓住它?

是的,这是我的错。但我使用静态、强类型语言的部分原因是它可以帮助我发现这些愚蠢的错误。

首先我检查了我实际上并没有将它初始化为某些损坏或被破坏的对象(也许它 初始化 - 只是很糟糕)。但是不,它在声明和第一次使用之间确实是未初始化的:

然后我想也许我已经关闭了警告:

Variable might not have been initialized

但是不,它已启用(在全球范围内,对于我的平台,对于我的发布类型):

所以我再次构建它(即使这个错误已经在代码中存在了几个月),以确保我没有错过错误。但不是;除了 VCL 和 JVCL 中的一些错误,Delphi 没有捕捉到错误:

我要Delphi帮助我

这是什么原因?

知道我的代码中是否有任何其他地方有同样的、可怕的、可怕的、完全可检测的错误.

可能是 64 位编译器。有人抱怨 64 位 back-end(全新)不如 32 位后端智能。如果我尝试将其更改为 32 位会怎么样?

还是没有:

与 32 位 release 和 64 位 release.

相同

1/25/2015 - 它甚至显示这样的警告吗?

重现警告的步骤 显示:

procedure TForm1.FormCreate(Sender: TObject);
var
    silverWarrior: Integer;
begin
    IsWrong(silverWarrior);
end;

function TForm1.IsWrong(n: Integer): Boolean;
begin
    Result := True;
end;

发出警告:

W1036 Variable 'silverWarrior' might not have been initialized

您甚至不必将值传递给另一个函数;简单地 使用 一个未初始化的变量给出警告(取决于特定日期编译器的心情):

procedure TForm1.FormCreate(Sender: TObject);
var
   silverWarrior: Integer;
   theAnswer: Integer;
begin
   theAnswer := silverWarrior + 42;
end;

给出警告:

W1036 Variable 'silverWarrior' might not have been initialized

超过 32 个局部变量导致失败?

否;你仍然收到警告:

procedure TForm1.FormCreate(Sender: TObject);
var
    localVariable1: Integer;
    localVariable2: Integer;
    localVariable3: Integer;
    localVariable4: Integer;
    localVariable5: Integer;
    localVariable6: Integer;
    localVariable7: Integer;
    localVariable8: Integer;
    localVariable9: Integer;
    localVariable10: Integer;
    localVariable11: Integer;
    localVariable12: Integer;
    localVariable13: Integer;
    localVariable14: Integer;
    localVariable15: Integer;
    localVariable16: Integer;
    localVariable17: Integer;
    localVariable18: Integer;
    localVariable19: Integer;
    localVariable20: Integer;
    localVariable21: Integer;
    localVariable22: Integer;
    localVariable23: Integer;
    localVariable24: Integer;
    localVariable25: Integer;
    localVariable26: Integer;
    localVariable27: Integer;
    localVariable28: Integer;
    localVariable29: Integer;
    localVariable30: Integer;
    localVariable31: Integer;
    localVariable32: Integer;
    localVariable33: Integer;
    localVariable34: Integer;
    localVariable35: Integer;
    localVariable36: Integer;
    localVariable37: Integer;
    localVariable38: Integer;
    localVariable39: Integer;
    localVariable40: Integer;
    localVariable41: Integer;
    localVariable42: Integer;
    localVariable43: Integer;
    localVariable44: Integer;
    localVariable45: Integer;
    localVariable46: Integer;
    localVariable47: Integer;
    localVariable48: Integer;
    localVariable49: Integer;
    silverWarrior: Integer;
    theAnswer: Integer;
begin
    theAnswer := silverWarrior + 42;
end;

W1036 Variable 'silverWarrior' might not have been initialized

就是这样。编译器在发现此类错误方面并不完美。除了您的问题(编译器无法警告的未初始化变量)之外,很可能会遇到编译器警告的已初始化变量。雪上加霜的是,32 位编译器可能会发出警告,而 64 位编译器却不会。反之亦然,有时 64 位编译器会发出警告,而 32 位编译器不会。

我没有找到任何模式。我没有办法。我有一个暗示,像 breakexit 这样的控制语句可能与这些问题有关,但我没有确凿的证据。

只有 Embarcadero 可以解决这个问题,所以您最好提交错误报告并希望 Embarcadero 的人关心。

我知道至少有 1 种可能会丢失此警告的情况。

QC#62702 Compiler should give warning for uninitialized object variables (archive.is)

简而言之,似乎如果变量作为 varout 参数传递给第二个函数,它会禁用整个当前函数的警告。

procedure A
var obj : Tobject;
begin
  obj.Free; <--Warning here
end;

procedure B
var obj : Tobject;
begin
  obj.Free; <--No warning here, even if it's only passed as var/out after this line.
  FreeAndNil(obj);
end;

另一个因素:Delphi 的变量跟踪中有一个 will-not-fix "bug"。如果你有超过 32 个局部变量,它会严重崩溃。由于那不是合理的代码,他们对此没有采取任何措施。

你能打中这个吗?