代码之家  ›  专栏  ›  技术社区  ›  Mason Wheeler

避免“变量可能尚未初始化”

  •  12
  • Mason Wheeler  · 技术社区  · 14 年前

    procedure TMyForm.DoSomething(list: TList<TMyObject>; const flag: boolean);
    var
      local: integer;
    begin
      if flag then
        //do something
      else local := ExpensiveFunctionCallThatCalculatesSomething;
    
      //do something else
      for i := 0 to list.Count do
        if flag then
          //do something
        else if list[i].IntValue > local then //WARNING HERE
            //do something else
    end;
    

    Variable 'local' might not have been initialized 即使通过阅读代码可以看出,除非初始化代码的代码分支已经运行,否则不会命中该行。

    现在,我可以通过添加一个无用的 local := 0; 在程序的顶部,但我想知道是否有更好的方法来构建这个结构以避免问题。有人有什么想法吗?

    5 回复  |  直到 14 年前
        1
  •  12
  •   Neil    14 年前

    我将它分为两个for循环——一个用于标志为true时,另一个用于标志为false时。另外一个好处是,您不必在每次迭代时都执行if语句。

        2
  •  6
  •   Chris Thornton    14 年前

        3
  •  6
  •   Deltics    14 年前

    根据flag参数重构代码以包含两个单独的流:

    procedure TMyForm.DoSomething(list: TList<TMyObject>; const flag: boolean);
    var
      local: integer;
    begin
      if flag then
      begin
        //do something
        //do something else
        for i := 0 to Pred(list.Count) do
          //do something
      end
      else
      begin
        local := ExpensiveFunctionCallThatCalculatesSomething;
    
        //do something else
        for i := 0 to Pred(list.Count) do
          if list[i].IntValue > local then
            //do something else
      end;
    end;
    

    这从本质上重申了 尼尔·惠特克1 ,但也明确了 地方的 变量将被带到条件分支内部,这是处理编译器警告的内容(仅当变量在可能未初始化的分支中使用时才会发出警告-在根本不使用它的分支中不会发出此类警告,并且在使用它的分支中肯定会被初始化,因为

    如果任何“//something”对于每个分支来说都是公共的,那么当然可以将它们重构为本地的嵌套过程,以避免重复。

        4
  •  1
  •   sabri.arslan    14 年前

    加局部:=0好解。

    据我所知,编译器会给出提示,因为即使在运行时检查标志,变量也可能未赋值,代码也无法按预期运行。

    对不起,我的英语不好:)

        5
  •  1
  •   Carl Manaster    14 年前

    我会把你的程序改成

    procedure TMyForm.DoSomething(list: TList<TMyObject>; const flag: boolean);
    var
      local: integer;
    begin
      if flag then
       begin
         local := 0;
         //do something
       end
      else local := ExpensiveFunctionCallThatCalculatesSomething;
    

    等。。。