我正在使用PascalScript innosetup安装程序,但我无法看到下一个块的控件在哪里流动。
function Foo(): String;
begin
Result := 'foo';
RaiseException('...');
end;
procedure Test();
var
Z : String;
begin
Z := '';
try
Z := Foo();
except
Log(Z);
end
end;
我的安装程序似乎表明Z
正在使用Result
功能的Foo
进行设置。我对“大多数”编程语言中的异常的理解告诉我,在异常的情况下不应该发生作业Z := Foo()
。
当Foo
函数提升时,是否仍应将Z
分配给?
答案 0 :(得分:2)
可能它通过引用处理结果值作为隐式的第一个参数。但是这可能发生。它可以被认为是某些代码生成/优化的合法性,因为它是处理返回值的一种常见方式。
然而,在Object Pascal外部测试中究竟定义的是Delphi所做的是黑暗的领域,因为只有x86和x86_64实现。并且Delphi将返回eax中的值,因此如果您遵循该逻辑,则这是非法的。
稍后补充:
我使用结构化类型测试了Delphi,并且在传递引用时,它会在堆栈上创建一个副本来传递它。
这可能会使用结构化类型优化代码变得困难,但是声明返回类型const的修饰符/属性可以在需要时修复它。
答案 1 :(得分:2)
在Delphi中,作为结果值的字符串被视为var
个参数。换句话说,像Foo这样的函数实际上被编译为:
procedure Foo(var Result: string);
begin
Result := 'Foo';
RaiseException(...);
end;
这意味着Z
(通过引用参数)会立即分配值'Foo'
,即之前引发异常。
换句话说,函数结果不只是保存在一个名为Result
的局部变量中,然后在函数结束时返回 - 这将被异常阻止 - 它会立即分配。
我认为这正是PascalScript中发生的事情。