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

时间:2015-01-23 16:48:17

标签: delphi delphi-xe6

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

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没有抓到它?

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

首先,我检查了我实际上并没有将其初始化为某些损坏或被破坏的对象(可能 已初始化 - 只是非常糟糕)。但不,它在申报和首次使用之间确实没有初始化:

enter image description here

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

  

变量可能尚未初始化

但不,它已启用(全局,对于我的平台,对于我的发布类型):

enter image description here

然后我再次构建它(即使这个bug在代码中存在了几个月),以确保我没有错过错误。但不是;除了VCL和JVCL中的一些错误外,Delphi并没有发现错误:

enter image description here

我希望Delphi帮助我

有什么可以解释这个?

知道我的代码中是否还有其他地方存在同样的,可怕的,可怕的,完全可检测到的错误。

也许它是64位编译器。有些人抱怨64位后端(全新的)并不像32位后端那样智能化。如果我尝试将其更改为32位怎么办?

仍然没有:

enter image description here

与32位版本和64位版本相同。

2015年1月25日 - 它是否显示出这样的警告?

重现警告的步骤 显示:

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

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

发出警告:

  

W1036变量' silverWarrior'可能尚未初始化

enter image description here

你甚至不必将价值传递给另一个职能部门;只需使用一个未初始化的变量就会发出警告(取决于特定日期编译器的情绪):

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

发出警告:

  

W1036变量' silverWarrior'可能尚未初始化

超过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变量' silverWarrior'可能尚未初始化

3 个答案:

答案 0 :(得分:4)

那是怎么回事。编译器在发现此类错误方面并不完美。除了您的问题(编译器未能警告的未初始化变量)之外,很可能遇到编译器发出警告的初始化变量。为了弥补痛苦,可能会有32位编译器发出警告的代码,但64位编译器却没有。反之亦然,有时64位编译器会发出警告,而32位编译器则不会。

我没有找到任何模式。我没有解决方案。我清楚地知道像breakexit这样的控制语句可能会与这些问题相关联,但我没有得到确凿的证据。

只有Embarcadero可以解决这个问题,所以你能做的最好的就是提交一份错误报告,并希望Embarcadero的某个人关心。

答案 1 :(得分:4)

我至少知道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;

答案 2 :(得分:0)

另一个因素:Delphi的变量跟踪中存在一个不会修复的“错误”。如果你有超过32个局部变量,它会严重破坏。由于这不是合理的代码,因此他们没有采取任何措施。

你可以点击这个吗?