在嵌套方法中访问时,由闭包捕获破坏的局部变量

时间:2017-08-14 19:00:19

标签: delphi closures anonymous-function delphi-10-seattle

我设法将此问题减少到:

program Project1;
{$APPTYPE CONSOLE}

uses
  SysUtils, Threading;

procedure Foo(AString: string);
var
  LTask : ITask;
  capturedString : string;
  procedure Nested;
  begin
    try
      WriteLn('Nested : ' + capturedString); { ! EIntOverflow (Win32) here }
    except on E : Exception do
      WriteLn(E.Message);  
    end; 
  end;
begin
  capturedString := AString;
  WriteLn('Local : ' + capturedString);
  Nested;
  LTask := TTask.Create(
    procedure
      procedure AnonNested;
      begin
        WriteLn(capturedString); { Removing this eliminates the problem }
      end;
    begin
    end);
end;

begin
  Foo('foo');
  ReadLn;
end.

当从嵌套方法中访问时,capturedString变量会被破坏。 Win32编译引发EIntOverflow,Win64编译写出一个(损坏的)空字符串 - 可以通过某种操作将构建引入AV或其他异常,但在所有情况下,当进入本地变量时,对本地变量的引用都会被破坏Nested程序。

这似乎只有在闭包中捕获capturedString时才会发生。

出了什么问题?

1 个答案:

答案 0 :(得分:3)

这似乎是一个编译器错误:

#RSP-18833: Capture by closure corrupts local variable used in nested method

解决方法是在匿名方法中使用第二个变量进行捕获:

morse.charAt(i)