delphi OUT参数的行为与文档不符

nfeuvbwi  于 2022-11-23  发布在  其他
关注(0)|答案(2)|浏览(168)

在Emba的website上,声明OUT参数(没有说明是哪种类型,所以我假设它适用于所有类型)不应该用于输入,因为它的值被“丢弃”。
通过丢弃,我解释(即使我们不在圣经学习时间)值为零。
但是,使用out参数时,被引用变量的初始值将被传递到的例程丢弃。
但是这个简单的代码表明,在任何情况下(整数/记录),存储在“i”中的值都不会被丢弃!

Procedure TestInteger(OUT i: Integer);
Begin
 if i = 7
 then i:= 14;
End;

TYPE TMyRec = record
  i: Integer;
end;

Procedure TestRec(OUT R: TMyRec);
Begin

End;

procedure TfrmTest.btnTestClick(Sender: TObject);
begin
  VAR i: Integer:= 7;
  TestInteger(i);

  VAR MyRecord: TMyRec;
  MyRecord.i:= 7;
  TestRec(MyRecord);
  Caption:= IntToStr(MyRecord.i);
end;

那么,是文档错了吗?是我的“解释”错了,还是编译器错了?

iecba09b

iecba09b1#

out修饰参数意味着该参数将仅用于向调用方返回值;例程不必对参数的初始值进行任何假设。
out修饰作为程序员的语义提示。此外,编译器 * 可以 * 使用“传递的”值将不会用于优化生成的代码的知识。
然而,并不能保证“传递”的值确实被清除。相反,它可能会迫使编译器生成效率稍低的代码(因为将内存清零需要时间)。
假设有一家手表制造商生产的手表在零下50°C也能正常工作,那么你订购的手表只需在零下20°C也能正常工作。制造商可能会利用这一知识以更低的成本生产手表。但是,绝对不能保证你交付的手表在零下50°C也会出现故障。一般情况下,您也不需要这样的保证。(当然,您不能在零下20°C以下使用腕表。)
但是,使用out参数时,被引用变量的初始值将被传递到的例程丢弃。
好吧,既然程序员从来没有使用过这个值,那么它实际上就被“丢弃”了,不是吗?
稍晚一点在同一页上写下来:
在程序控制传递给过程之前,调用GetInfo会立即释放MyRecord使用的内存。
好吧,这很难不被认为是错误的。

cig3rfwq

cig3rfwq2#

请注意,如果使用托管记录,它将调用initialize,并在标题中以0结尾。

TYPE TMyRec = record
  i: Integer ;
  class operator Initialize (out Dest: TMyRec);
end;

class operator TMyRec.Initialize (out Dest: TMyRec);
begin
  dest.i := 0;
end;

这更像是一个注解,但是代码在注解中的格式不好。

相关问题