gpt4 book ai didi

delphi - 当函数中引发异常时,TStrings 返回为 "Inaccessible value"

转载 作者:行者123 更新时间:2023-12-03 15:10:11 26 4
gpt4 key购买 nike

有人可以帮我解释为什么当底层函数中引发异常时 TStrings 会作为“不可访问的值”返回吗?

function GetStrings():TStrings;
begin
result := TStringList.Create;
try
raise exception.Create('Error Message');
except
FreeAndNil(result);
raise
end;
end;

procedure TFormMain.Button1Click(Sender: TObject);
var
S : TStrings;
begin
try
S := GetStrings;
try
//Do awesome stuff
finally
FreeAndNil(S)
end;
except
//Debug watch: S = "Inaccessible value"
Assert(S = nil, 'Assertion failure, S should be nil');
end;
end;

如果我在重新引发异常之前不调用 FreeAndNil(result);,函数 GetStrings 也会返回“不可访问的值”。然而,我手上也有内存泄漏:-O

最佳答案

try
S := GetStrings;
try
//Do awesome stuff
finally
FreeAndNil(S)
end;
except
//Debug watch: S = "Inaccessible value"
Assert(S = nil, 'Assertion failure, S should be nil');
end;

执行顺序如下:

  1. 由于S是局部变量,因此在初始化之前其值是不确定的。这就是此代码开始执行时的状态。
  2. 调用 GetStrings 函数。
  3. GetStrings 中引发异常。这意味着 GetStrings 不会将执行返回给调用者,因此导致 S 永远不会被分配。
  4. finally block 不会执行,因为它的 try 从未到达。
  5. 接下来,except block 执行,并且 S 具有不确定的值,正如您所观察到的。

事实上,编译器应该警告 (W1036):当您在 except block 中引用 S 时,它可能尚未初始化。但它似乎无法做到这一点,这是相当可悲的。

如果您希望能够在 except block 中引用 S,则需要将其嵌套在 try/finally 中。

S := GetStrings; 
try
try
//Do awesome stuff
except
//Do stuff with S
Assert(S <> nil);
end;
finally
FreeAndNil(S)
end;

另一种思考方式是,S 仅在分配给 S 的代码和销毁对象的代码之间才有意义。结果是,如果 except block 要能够引用,则 try/except 必须嵌套在 try/finally 内。对象。

关于delphi - 当函数中引发异常时,TStrings 返回为 "Inaccessible value",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25310611/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com