2017-08-14 25 views
8

tôi đã quản lý để giảm bớt vấn đề này như sau:biến địa phương bị phá vỡ bởi chụp đóng cửa khi truy cập trong phương pháp lồng nhau

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. 

Đây biến capturedString bị hỏng khi truy cập từ bên trong một phương pháp lồng nhau. Một biên dịch Win32 tăng EIntOverflow, một biên dịch Win64 ghi ra một chuỗi rỗng (tham nhũng) - hoặc xây dựng có thể được kích thích thành AV hoặc các ngoại lệ khác với một số thao tác nhưng trong mọi trường hợp tham chiếu đến biến cục bộ bị hỏng khi nhập thủ tục Nested.

Điều này dường như chỉ xảy ra nếu capturedString được ghi lại trong trạng thái đóng.

Có gì không ổn?

Trả lời

3

Điều này có vẻ giống như một lỗi biên dịch:

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

Một cách giải quyết là sử dụng một biến thứ hai để chụp trong phương pháp vô danh:

procedure Foo(AString: string); 
var 
    LTask : ITask; 
    capturedString, s2 : string; 
    procedure Nested; 
    begin 
    try 
     WriteLn('Nested : ' + capturedString); 
    except on E : Exception do 
     WriteLn(E.Message); { !!! } 
    end; 
    end; 
begin 
    capturedString := AString; 
    s2 := capturedString; 
    WriteLn('Local : ' + capturedString); 
    Nested; 
    LTask := TTask.Create(
    procedure 
     procedure AnonNested; 
     begin 
     WriteLn(s2); { Capture another variable } 
     end; 
    begin 
    end); 
end; 
Các vấn đề liên quan