0

我会放一段代码,一个函数。

代码完美运行,没有永远循环。

让我生气的是编译器警告系统。

在编译器警告上,它说有一个永远不会结束的循环,因为它的条件“总是评估为 False”,这是完全错误的,条件可以是 True,如果运行它会进入循环并结束。

是的,我可以忽略这样的警告信息,但我希望它不会显示...我知道这是编译器警告系统上的一个 BUG,有没有修复?

这是一段代码(阅读评论以了解我为什么这样写):

function DoSomethingRetrying(ReTries:Byte=3):Boolean;
var
   HasSucceeded:Boolean;
begin // Do something till not fail, retrying no more than a given number of times
     HasSucceeded:=False; // Initial value to indicate it has not yet succeeded
     repeat // Enter into the ReTry loop till not fail or had tried more than a given number of times
           Dec(ReTries); // Reduces the number of retries to ensure that the loop will end when done more than a given number of times.
           try // Just to caught some kind of error
              // Here can go a tipical AssigFile sentence
              try // Just to caught some kind of error
                 // Here can go a tipical Reset sentence
                 // Here can go a tipical Read sentence
                 try // Just to caught some kind of error
                    // Here can go some ':=' sentences to move data form the record to variables, maths, etc
                    HasSucceeded:=True; // Set the condition so the loop will end immediately.
                 except // Something went wrong
                       // Here you can put some code in case needed
                 end;
              finally // Just in case something is mandatory to be done, if failed or not.
                     // Here can go a tipical CloseFile sentence
              end;
           except // Something went wrong
                 Sleep(1); // Just make a little pause between retries
                 HasSucceeded:=DoSomethingRetrying(ReTries); // ReTry it again (with counter one less)
           end;
     until HasSucceeded or (0>ReTries); // Repeat the loop till no fail or done a max number of retries
     DoSomethingRetrying:=HasSucceeded; // Return if has succeeded
end;

只需将代码(原样,无需任何修改)添加到实现部分的任何单元......然后编译它......警告将显示文本: W1021 Comparison always evaluates to False

如果您分析代码,您将看到:

  1. 它放在False变量HasSucceeded
  2. 进入repeat...until循环内
  3. 递减ReTries变量,所以它比传递的少一(它可以是负数)
  4. 在一些try块内,它放在True变量HasSucceeded
  5. 事实上,它永远不会运行该Sleep(1)部件。该部分适用于大多数外部try进入该except部分的情况,例如,如果AssignFile失败(文件不存在等)
  6. 它将评估until条件,HasSucceeded变量具有值True,也可以是真实的(0>ReTries)部分(例如当ReTries具有负值时)
  7. 它退出repeat...until循环
  8. 该函数将返回HasSucceeded值(在这种情况下True

但无需深入了解代码内部......想象一下我用这些句子之一来称呼它: DoSomethingRetrying(0); DoSomethingRetrying(-1);

在这种情况下,until条件部分(0>ReTries)将是True.

编译器怎么敢说HasSucceeded or (0>ReTries)总是被评估为假?

此外,运行代码(如果您愿意,请逐步运行),您会看到它结束,因此条件可以被评估为True,并非总是如此False......编译器警告消息位于!!!

所以,我想知道如何在不停用此类警告消息类型的情况下解决它?

提前致谢!

PD:至少它发生在 turbo Delphi 2006 上(尚未与其他人一起测试)。

4

2 回答 2

14

您的ReTries变量具有 type Byte,这是一个无符号类型。由于它是无符号的,它的值总是大于或等于零。因此,比较0 > Retries确实总是错误的。您在步骤 3 中断言该值可能为负数是错误的,因此编译器正确地警告您。

在您试图禁用编译器提示或警告之前,请绝对确保编译器实际上是错误的。

于 2013-03-14T15:53:49.733 回答
2

根本不是错误:编译器发出警告是正确的

在这种情况下,直到条件部分 (0>ReTries) 将为 True。

你永远不会是正确的,因为 ReTries 是 Byte 类型的 :)

已成功:=真;

如果 Dec(ReTries) 永远不会发生;引发异常:)

于 2013-03-14T16:01:43.117 回答