2017-06-02 121 views
3

我偶然發現了一個意外的Delphi 2009行爲。在調查了我的代碼中的一個奇怪的錯誤之後,我設法縮小了這個問題的範圍,並創建了一個我在下面展示的最小示例。Delphi匿名函數傳遞給內聯函數

當然,下面的代碼打印值1:

program Example1; 

{$APPTYPE CONSOLE} 

type 
    TIntFcn = reference to function(const X: integer): integer; 

function fcn(AFunction: TIntFcn; a: integer): integer; inline; 
begin 
    result := AFunction(a); 
end; 

begin 

    writeln(fcn(function(const X: integer): integer 
    begin 
     result := 1; 
    end, 0)); 

end. 

類似地,此程序將打印值2:

program Example2; 

{$APPTYPE CONSOLE} 

type 
    TIntFcn = reference to function(const X: integer): integer; 

function fcn(AFunction: TIntFcn; a: integer): integer; inline; 
begin 
    result := AFunction(a); 
end; 

begin 

    writeln(fcn(function(const X: integer): integer 
    begin 
     result := 2; 
    end, 0)); 

end. 

「顯然」,該第三程序將打印相同的值第一個,即1:

program Produce; 

{$APPTYPE CONSOLE} 

type 
    TIntFcn = reference to function(const X: integer): integer; 

function fcn(AFunction: TIntFcn; a: integer): integer; inline; 
begin 
    result := AFunction(a); 
end; 

begin 

    writeln(fcn(function(const X: integer): integer 
    begin 
     result := 1; 
    end, 0)); 

    fcn(function(const X: integer): integer 
    begin 
     result := 2; 
    end, 0); // discard the output 

end. 

但是,輸出不是1,而是2。 ler使用fcnwriteln調用中的第二個匿名函數。

對我來說,這似乎是Delphi 2009編譯器中的一個錯誤,但它也可能只是我不理解Delphi中匿名函數的更細微的細節。你怎麼看?

+1

FWIW,在10.2東京,顯示'1'。在XE中也是如此。所以這可能是一個在Delphi 2009中如何處理匿名函數的bug。 –

+0

我假設第二個匿名函數以某種方式取代了第一個匿名函數。但我不知道如何。但對我來說,它在Delphi 2009中看起來也是一個bug。 –

+1

@RudyVelthuis,剛剛在Quality Central進行搜索,發現它不見了!?發生什麼事?我同意這個無框架在這裏被錯誤地重用,導致第一個被替換。 –

回答

1

這肯定是一個bug,根據收到的意見,Delphi XE已經修復了這個問題。也許最簡單的解決方法是跳過詢問如果編譯器不能正確處理它內聯:

program Solve; 

{$APPTYPE CONSOLE} 

type 
    TIntFcn = reference to function(const X: integer): integer; 

function fcn(AFunction: TIntFcn; a: integer): integer; 
    {$IF CompilerVersion >= 22}inline;{$IFEND} {Warning: Horrible bug in Delphi 2009} 
begin 
    result := AFunction(a); 
end; 

begin 

    writeln(fcn(function(const X: integer): integer 
    begin 
     result := 1; 
    end, 0)); 

    fcn(function(const X: integer): integer 
    begin 
     result := 2; 
    end, 0); // discard the output 

end. 

在大多數情況下,性能的損失應該是在2009年德爾福可以忽略不計,而你做的請求內聯在XE及更高版本。當然,如果你不認爲內聯很重要,你可以簡單地刪除請求。

相關問題