J'ai réussi à réduire ce problème à ceci:Variable locale brisée par la capture de fermeture en cas d'accès dans la méthode imbriquée
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.
Ici la variable capturedString
est corrompue quand on y accède à partir d'une méthode imbriquée. Une compilation Win32 lève EIntOverflow
, une compilation Win64 écrit une chaîne vide (corrompue) - la construction peut être provoquée en AV ou d'autres exceptions avec quelques manipulations mais dans tous les cas la référence à la variable locale est corrompue lors de la procédure Nested
.
Cela semble se produire uniquement si capturedString
est capturé dans une fermeture.
Qu'est-ce qui ne va pas?