如果记录了返回值,则缺少“函数的返回值可能未定义”

时间:2018-07-18 19:53:36

标签: delphi warnings record

当我在Delphi 10.2.3 Pro中编写一个函数,该函数具有记录作为返回值,而只是将其保留为空时,我不会收到W1035“ W1035函数'%s'的返回值可能未定义”的警告。为什么我没有收到警告?

谢谢!

2 个答案:

答案 0 :(得分:1)

不幸的是,对于非托管记录,警告也被取消。我猜想原因是编译器很难跟踪所有字段的变化。另外,如果您修改记录的一个字段,是否将整个记录视为已定义?

这是要测试的代码:

{$O-}

type
  TRecordType = record
    a, b: Word;
  end;

function Test: TRecordType;
begin
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  v: TRecordType;
begin
  v := Test;
  ShowMessage(Format('%d, %d', [v.a, v.b]));
end;

它确实为我提供了随机数(如果重复运行,则不会更改,因为堆栈几乎相同)。

用于调用的汇编代码:

0046CCA9 E8CAFFFFFF       call Test
0046CCAE 8945F8           mov [ebp-$08],eax

Test的汇编代码:

0046CC78 55               push ebp
0046CC79 8BEC             mov ebp,esp
0046CC7B 51               push ecx
0046CC7C 8B45FC           mov eax,[ebp-$04]   ; eax is the result, not initiated
0046CC7F 59               pop ecx
0046CC80 5D               pop ebp
0046CC81 C3               ret 

当记录的大小不是1、2、4时,结果将通过引用作为隐藏参数传递。例如,如果abinteger,则用于调用的汇编代码将变为

0046CCAA 8D45F4           lea eax,[ebp-$0c]   ; address of V, V is not initiated
0046CCAD E8C6FFFFFF       call Test

Test的汇编代码:

0046CC78 55               push ebp
0046CC79 8BEC             mov ebp,esp
0046CC7B 51               push ecx
0046CC7C 8945FC           mov [ebp-$04],eax
0046CC7F 59               pop ecx
0046CC80 5D               pop ebp
0046CC81 C3               ret 

因此,在两种情况下,结果都是不确定的,没有警告。

答案 1 :(得分:0)

从我的角度来看,这显然是编译器警告生成器中的错误。

对于记录,编译器必须比对整数或实数之类的简单类型进行更多检查。例如,您在这里期望什么:

function Test: TRecordType;
begin
  result.a := 1;
end;

因为记录的一部分(对于b而言)是未定义的,所以编译器在此处也应提及W1035。另一方面,对于具有不同案例的记录,您会有什么期望?

TRecordType = record
  ID: string;
  case boolean of
    true:
      (a: integer);
    false:
      (b: string);
end;

正如您在此处看到的,无法确定记录是否已完全初始化。至少如我们在TRecordType是类的情况下所见,如果未分配记录的静态字段,则至少Delphi编译器可以发出警告。

我建议在Embarcadero质量报告端输入此错误 https://quality.embarcadero.com 并在堆栈溢出时对此线程进行引用。