在一个单元中我使用该函数DeleteFile,编译器输出一个提示:
"H2443内联函数'DeleteFile'尚未展开,因为在USES列表中未指定单位'Windows'"
在Uses那里SysUtils,它定义DeleteFile(虽然内部调用Windows.DeleteFile).
这个提示意味着什么?如果我Windows加入该Uses条款,它已经消失了,但我想了解困扰编译器的是什么.
Dav*_*man 24
这是一个内联限制.
请参阅Hallvard Vassbotn关于Inlined Routines的文章.
从该网站提取:
其余的内联限制对于两个平台都是通用的,而最重要的是
- 没有跨包边界内联
- 内联例程无法访问实现部分标识符
- 呼叫站点必须能够访问内联例程中使用的所有标识符
注意最后一点意味着除非调用站点单元使用例程所需的单位,否则不能内联例程.发生这种情况时,编译器会发出这样的提示
Run Code Online (Sandbox Code Playgroud)[Pascal Hint] InlinedRoutinesU.pas(14): H2443 Inline function 'InlineMe' has not been expanded because unit 'RequiredUnit' is not specified in USES list要解决此问题,请将缺少的单元名称添加到调用站点的uses子句中.
Too*_*the 12
内联函数可以内联扩展.例如:
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.
Run Code Online (Sandbox Code Playgroud)
被重写为:
var
x,y,z : Integer;
begin
y := 22;
z := 11;
x := y+z+1;
end.
Run Code Online (Sandbox Code Playgroud)
这消除了函数调用的开销.
但是为了用函数体替换调用,编译器需要更多的信息,因此关于单元的抱怨.
请注意,并非所有内联函数都已转换.有些被视为普通函数(由编译器决定).此外,仅在非常严格的性能瓶颈时才需要内联.
我也对这个提示感到困惑.然后我意识到问题是什么.你的代码:
uses
SysUtils;
procedure TForm1.DoStuff;
begin
SysUtils.DeleteFile('foo');
end;
Run Code Online (Sandbox Code Playgroud)
实际上被替换为:
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;
Run Code Online (Sandbox Code Playgroud)
如果您注意到,您的"新"代码取决于WinApi.Windows单位:
Result := Winapi.Windows.DeleteFile(PChar(FileName));
Run Code Online (Sandbox Code Playgroud)
您未在uses条款中包含的内容.
如果手动内联代码(复制和粘贴),代码将无法编译,直到您添加Windows到您的代码uses.
相反,编译器不会这样做,inline因为:
内联函数'DeleteFile'尚未展开,因为在USES列表中未指定单位'Windows'
| 归档时间: |
|
| 查看次数: |
10160 次 |
| 最近记录: |