delphi 尝试编译此代码会导致IDE终止或编译器无法运行,这是否是一个错误?

oyjwcjzk  于 2023-06-29  发布在  其他
关注(0)|答案(3)|浏览(102)

注意内联函数中的Exit命令用法!我一直在使用 Delphi XE 3。

症状

在某些情况下,当调用包含Exit命令的内联函数,并且在WriteLn()中 * 直接 * 使用内联函数的 * 返回值 * 时,编译器报告错误消息。
“dcc”退出,代码为1。
甚至更糟糕的是, Delphi IDE在没有任何确认的情况下终止。

function ProcessNumber(const iNumber: Integer): Boolean; inline;
begin
  if iNumber = 0 then begin
    Result := False;
    Exit;
  end;
  // some code here ...
  Result := True;
end;

procedure Test;
begin
  writeln( ProcessNumber(0) );
end;

begin
  Test;
  ReadLn;
end.

但是,如果内联函数的 * 返回值 * 存储在变量中,然后在WriteLn()中使用该变量,则不会发生问题。

procedure Test;
var
  b: Boolean;
begin
  b := ProcessNumber(0);
  writeln(b);
end;

常见问题

1.这是一个编译器bug吗?
1.如果这是一个bug,有没有一个解决方法可以安全地退出内联函数?

knpiaxh1

knpiaxh11#

这肯定是一个bug。它出现在我测试的所有IDE版本中,XE 3,XE 7和XE 8。我真的不认为你能做什么。对我来说,IDE每次编译时都会终止。我认为你只需要以一种不会导致IDE崩溃的方式编写代码。
可以使用强制编译使用msbuild的IDE选项。这将把编译放到一个单独的进程中,从而确保IDE不会崩溃。但这对你没有太大帮助,因为尽管你的IDE不会继续消亡,你仍然无法编译你的程序!
当你使用msbuild构建时,你会得到一个如下形式的错误:
错误F2084:内部错误:GPFC00000FD-004D3F34-0
GPF代表General Protection Fault,即内存访问违规。这可能是一个未处理的异常,当编译在进程中执行时,它会关闭IDE。
我的建议是你提交一个bug报告给Quality Portal。这是修复缺陷的唯一方法。尽管不要指望XE 3会有一个修复。

iklwldmw

iklwldmw2#

这里可以使用的一种解决方法是反转if条件实现,从而完全避免使用Exit命令。
所以我们不用

function ProcessNumber(const iNumber: Integer): Boolean; inline;
begin
  if iNumber = 0 then begin
    Result := False;
    Exit;
  end;
  // some code here ...
  Result := True;
end;

使用

function ProcessNumber(const iNumber: Integer): Boolean; inline;
begin
  if iNumber <> 0 then begin
    // some code here
    Result := True;
  end;
  else
    Result := False;
    //No exit needed here as this is already at the end of your method
end;
kqlmhetl

kqlmhetl3#

在我们的例子中,当我们传递一个接口作为“var”参数时,会发生“dcc exited with code 1”。
我找到了解决此问题的方法。
首先,有两个bug在一个:
1.编译器无法正确显示错误消息。这是因为项目被设置为外部编译(在MSBuild中)。一旦我将该选项设置为默认值,编译器就能够显示实际的错误消息和发生错误的代码行/单元。
1.我们的框架有接收接口作为var参数的方法。64位编译器不喜欢这样。解决方案是删除var参数OR以从变量中删除[unsafe]装饰器。
_

procedure DoStuff(var i: ISomeInterface);  // Fix a: Remove "var"   
begin   
   // DoStuff may set the I parameter to Nil!  
end;

这样使用:

var  
   [unsafe] x: ISomeInterface;     // Fix b: Remove [unsafe]   
DoStuff(x);

相关问题