发现Delphi Tokyo中的异常处理与以前的Delphi版本略有不同.
function FuncTest: integer;
begin
Result := 1;
try
raise Exception.Create('Error Message');
finally
Result := 2;
end;
end;
function Test:integer;
begin
Result:=0;
try
Result:=FuncTest;
finally
ShowMessage(Result.ToString);
end;
end;
Run Code Online (Sandbox Code Playgroud)
在早期的Delphi版本中,消息框显示"2",东京 - "0".这是一个东京错误还是不应该像这样处理异常?
Dav*_*nan 15
东京的行为是正确的.引发异常的函数不返回值.到目前为止,您一直依赖于实现细节.
考虑以下代码:
Result:=FuncTest;
Run Code Online (Sandbox Code Playgroud)
执行如下:
FuncTest 叫做.Result 被安排了.现在,因为步骤1引发异常,所以步骤2不会执行.
如果有的话,我会说你从早期版本报告的行为是可疑的.在这个功能:
function Test:integer;
begin
Result:=0;
try
Result:=FuncTest;
finally
ShowMessage(Result.ToString);
end;
end;
Run Code Online (Sandbox Code Playgroud)
该语句Result:=FuncTest引发异常,因此Result不应该被该语句修改.另一种思考方式是调用函数但不执行赋值.
Delphi ABI的一个问题是函数返回值有时被实现为隐式var参数.这意味着任务可能会也可能不会发生.展示:
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
TRec1 = record
X1: NativeInt;
end;
TRec2 = record
X1: NativeInt;
X2: NativeInt;
end;
function GetRec1: TRec1;
begin
Result.X1 := 1;
raise Exception.Create('');
end;
function GetRec2: TRec2;
begin
Result.X1 := 1;
raise Exception.Create('');
end;
procedure Main;
var
Rec1: TRec1;
Rec2: TRec2;
begin
Rec1 := Default(TRec1);
Writeln(Rec1.X1);
try
Rec1 := GetRec1;
except
end;
Writeln(Rec1.X1);
Rec2 := Default(TRec2);
Writeln(Rec2.X1);
try
Rec2 := GetRec2;
except
end;
Writeln(Rec2.X1);
end;
begin
Main;
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
这输出:
0 0 0 1
这是相当令人失望的.不应该修改调用者的变量,但是使用隐式var参数而不是值返回允许这种泄漏.在我看来,这是Delphi ABI设计中的一个严重缺陷,这是一个你在大多数其他语言中都找不到的缺陷.
在您的代码中,没有var参数,因为返回类型在寄存器中传输.在这种情况下,任何输出的Delphi版本都会2被破坏.
从根本上说,你的代码在预期中是错误的.如果函数引发异常,则必须假定返回值是错误定义的.
最后,你的代码输出0在XE3和XE7中,所以我想知道你需要多远才能看到一个值2.
| 归档时间: |
|
| 查看次数: |
648 次 |
| 最近记录: |