2012-07-19 134 views
4

我得到一个编译器警告我不明白:编译器为什么警告该变量可能未被初始化?

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; 

当我在2010年德尔福编译这个我得到:

[DCC警告] OnlineClaimManagerMainU.pas(554):W1036变“VAR1” 可能尚未初始化

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

此外,如果我删除try/except子句(并保留继续),警告消失。

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

+1

编译器的分析是不深你的。不能确定Var1是否已经初始化。你知道Var1总是被初始化,但编译器没有你的分析天赋。 – 2012-07-19 06:12:38

+1

请...我红着脸:-) – awmross 2012-07-19 06:17:47

+0

所以...为什么去掉继续解决这个问题?同样的问题将适用。还是仅仅是两者结合的复杂性让编译器头脑发生了变化? – awmross 2012-07-19 06:21:19

回答

4

Var1将始终在使用前初始化。编译器会被try - except处理混淆:编码器的代码太复杂,无法真正确定Var1总是被初始化。它认为有可能是Var1:=6;前处理的异常,这会使Var1未初始化的,但它并没有看到那个例外总是会被重新提出。

+0

它不会,本地未管理的变量不会自动初始化。 – 2012-07-19 06:20:29

+0

@Cesar HVD是指使用 – 2012-07-19 06:21:38

+0

事实上,由于之前总是初始化。 – hvd 2012-07-19 06:34:26

0

您应该但ShowMessage(IntToStr(Var1));进入try除了块。 那么它应该是明确的编译器,这是Var1和intialized看起来更干净的代码。

+1

做这意味着,如果'ShowMessage'导致异常(是的,它可以做到这一点,而且,我假设它是从代码,并不仅仅是调用'ShowMessage'简体),异常处理程序将运行,而它不会在问题的代码中。 – hvd 2012-07-19 08:10:47

0

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

+1

我想你还没有明白这个问题。 – 2012-07-19 21:52:29

+0

@罗伯·肯尼迪我想你误解了我的答案。 Var1的值未在路径中分配。因此警告。如果您不同意,请为您的评论添加一些值。 – Rob 2012-07-20 09:11:46

+1

很好。这个问题没有问到警告的含义。它问为什么警告是在这种情况下给出的,特别是因为看似无关的变化影响警告的外观。人们很清楚Var1 *是在警告指出的地方分配的,但编译器没有看到。你的回答表明你认为警告是正确的;请说明如何。 – 2012-07-20 12:46:20

相关问题