编译器提示:“内联函数'......'尚未扩展......”

时间:2009-03-16 09:06:46

标签: delphi winapi

在一个单元中,我使用函数DeleteFile,编译器输出一个提示:

  

“H2443内联函数'DeleteFile'尚未展开,因为在USES列表中未指定单位'Windows'”

Uses中有SysUtils,其中定义DeleteFile(虽然内部调用Windows.DeleteFile)。

这个提示意味着什么?如果我将Windows放入Uses子句中,它已经消失了,但我想了解困扰编译器的是什么。

4 个答案:

答案 0 :(得分:24)

这是一个内联限制。

见Hallvard Vassbotn关于Inlined Routines的文章。

从该网站摘录:

  

其余的内联限制   这两个平台和平台都很常见   最重要的是

     
      
  • 没有内联包边界
  •   
  • 内联例程无法访问实现部分标识符
  •   
  • 呼叫站点必须能够访问内联中使用的所有标识符   常规
  •   
     
    

注意最后一点意味着除非呼叫站点单位使用例程所需的单位,否则无法内联例程。发生这种情况时,编译器会发出类似这样的提示

 [Pascal Hint] InlinedRoutinesU.pas(14): H2443 Inline function 
   'InlineMe' has not been expanded because unit 'RequiredUnit' 
    is not specified in USES list 
         

要解决此问题,请将缺少的单位名称添加到呼叫站点的uses子句中。

  

答案 1 :(得分:11)

内联函数可以内联扩展。例如:

function AddPlus(const A,B: Integer): Integer; inline;
begin
  Result := A + B + 1;
end;

var
  x,y,z : Integer;
begin
  y := 22;
  z := 11;
  x := AddPlus(y, z);
end.

重写为:

var
  x,y,z : Integer;
begin
  y := 22;
  z := 11;
  x := y+z+1;
end.

这消除了函数调用的开销。

但是为了用函数体替换调用,编译器需要更多的信息,因此关于单元的抱怨。​​

请注意,并非所有内联函数都已转换。有些被视为普通函数(由编译器决定)。此外,仅在非常严格的性能瓶颈时才需要内联。

答案 2 :(得分:7)

我也被这个提示弄糊涂了。然后我意识到问题是什么。你的代码:

uses
   SysUtils;

procedure TForm1.DoStuff;
begin
   SysUtils.DeleteFile('foo');
end;

实际上被替换为:

uses
   SysUtils;

procedure TForm1.DoStuff;
var
  Flags, LastError: Cardinal;
begin
  Result := Winapi.Windows.DeleteFile(PChar(FileName));

  if not Result then
  begin
    LastError := GetLastError;
    Flags := GetFileAttributes(PChar(FileName));

    if (Flags <> INVALID_FILE_ATTRIBUTES) and (faSymLink and Flags <> 0) and
      (faDirectory and Flags <> 0) then
    begin
      Result := RemoveDirectory(PChar(FileName));
      Exit;
    end;

    SetLastError(LastError);
  end;
end;

如果您发现,&#34;新&#34; 代码取决于WinApi.Windows单位:

Result := Winapi.Windows.DeleteFile(PChar(FileName));

您没有在uses条款中加入。

如果您手动内联代码(复制并粘贴),则在将Windows添加到uses之前,代码将无法编译。

相反,编译器不会执行inline因为:

  

内联功能&#39;删除文件&#39;尚未扩展,因为单位&#39; Windows&#39;未在USES列表&#34;

中指定

答案 3 :(得分:1)

内联函数由编译器扩展到位,避免了函数调用的开销。例如。对于平方,sqr(x)以x * x编译,而不是调用与x相乘的函数并返回结果。