我偶然发现了意外的Delphi 2009行为。在调查了我的代码中的一个奇怪的错误之后,我设法缩小了问题的范围并创建了一个最小的例子,我将在下面提供。
当然,以下代码打印值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.看起来编译器在fcn
的{{1}}调用中使用了第二个匿名函数。
对我而言,这似乎是Delphi 2009编译器中的一个错误,但它也可能只是我不了解Delphi中有关匿名函数的更细微的细节。你觉得怎么样?
答案 0 :(得分:1)
这肯定是一个错误,根据收到的问题的评论,这已在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.
在大多数情况下,Delphi 2009中的性能损失应该可以忽略不计,并且您确实要求在XE及更高版本中进行内联。当然,如果你不认为内联很重要,你可以简单地删除请求。