【问题标题】:Why is the Compiler warning that variable may not be initialized?为什么编译器警告变量可能未初始化?
【发布时间】:2012-07-18 06:49:39
【问题描述】:

我收到一个我不明白的编译器警告:

procedure Test;
var
  Var1: Integer;
begin
    while True do
    begin
        try
            if System.Random > 0.5 then
            begin
                ShowMessage('Skipping');
                continue; // If I remove this line, the warning goes away
            end;
            Var1:=6;
        except on
            E:Exception do
            begin
                ShowMessage('Error');
                raise;
            end;
        end;
        ShowMessage(IntToStr(Var1)); // Compiler warning on this line
    end;
end;

当我在 Delphi 2010 中编译它时,我得到:

[DCC 警告] OnlineClaimManagerMainU.pas(554): W1036 变量 'Var1' 可能还没有初始化

如果我删除对“继续”的调用,警告就会消失。

另外,如果我删除 try/except 子句(并离开 continue),警告就会消失。

在没有初始化 Var1 的情况下,如何执行到有问题的行?

【问题讨论】:

  • 编译器的分析没有你那么深。不能确定 Var1 是否已初始化。你知道 Var1 总是被初始化,但编译器没有你的分析能力。
  • 那么...为什么删除 continue 会修复它?同样的问题也适用。还是仅仅是两者结合的复杂性让编译器大吃一惊?
  • 添加 Var1:=0;之前让编译器高兴。
  • 我猜 continue 的存在意味着编译器的分析更加困难。有趣的是,我曾经有一些我知道很好但编译器警告过的代码,在 x86 中而不是 x64 中。我做了明显的改变,然后 x86 编译器安静了,但是 x64 编译器抱怨!很奇怪。
  • @cesar 没有抓住重点。问题是为什么编译器会警告永远不会发生的事情。

标签: delphi delphi-2010


【解决方案1】:

Var1 在使用前总是会被初始化。编译器对try-except 处理感到困惑:您的代码太复杂,编译器无法实际确定Var1 始终被初始化。它看到在Var1:=6; 之前可能有一个已处理的异常,这将使Var1 未初始化,但它没有看到该异常总是会重新引发。

【讨论】:

  • 不会,本地非托管变量不会自动初始化。
  • @Cesar hvd 表示使用前始终初始化
【解决方案2】:

您应该将 ShowMessage(IntToStr(Var1)); 放入 try except 块中。 然后编译器应该清楚,Var1 已初始化并且看起来更像是干净的代码。

【讨论】:

  • 这样做意味着如果 ShowMessage 导致异常(是的,它可以做到这一点,此外,我假设它是从不仅仅是调用 ShowMessage 的代码中简化的),异常处理程序将运行,而它不会在问题中的代码中运行。
【解决方案3】:

这是一个非常好的警告。它告诉您没有为可能在代码中其他地方使用的变量分配任何值。警告还告诉如果它被使用,那么分配给它的值可能不是你所期望的。

【讨论】:

  • 我想你还没有理解这个问题。
  • @Rob Kennedy 我想你误解了我的回答。 Var1 的值未在路径中分配。因此发出警告。如果您不同意,请为您的评论添加一些价值。
  • 很好。问题没有问警告的含义。它询问为什么在这种情况下发出警告,特别是因为看似不相关的变化会影响警告的外观。人类很清楚 Var1 在警告指示的位置被分配了,但编译器看不到这一点。您的回答表明您认为警告是正确的;请说明如何。
  • 我现在看到了,仅在分配 Var1 值时才执行对 ShowMessage(IntToStr(Var1)) 的调用。所以这个警告实际上没有意义。感谢 Rob K. 好心让我弄清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
相关资源
最近更新 更多