2009-03-16 4 views
14

In einer Einheit Ich verwende die Funktion DeleteFile und der Compiler gibt einen Hinweis:Compiler Hinweis: "Inline-Funktion '...' erweitert nicht ..."

„H2443 Inline-Funktion 'DeleteFile' hat nicht erweitert worden, weil Einheit 'Windows' nicht

in Uses in uses-Liste“angegeben ist es SysUtils, die DeleteFile definiert (obwohl intern Windows.DeleteFile Aufruf).

Was bedeutet dieser Hinweis? Wenn ich Windows in die Uses-Klausel einfüge, ist es weg, aber ich würde gerne verstehen, was den Compiler stört.

Antwort

23

Es ist eine Inline-Einschränkung.

Siehe Hallvard Vassbotn Artikel über Inlined Routines.

von dieser Seite ausgezogen:

Der Rest der inlining Einschränkungen sind für beide Plattformen gemeinsam und die wichtigsten sind

  • keine inlining über Paketgrenzen
  • die inlined Routine kann nicht Zugriff auf Implementation Abschnittsbezeichner
  • die Aufruf-Site muss Zugriff auf alle Identify haben rs in der inlined Routine
  • verwendet

Hinweis Der letzte Punkt bedeutet, dass es sei denn, die Aufrufort Einheit der Einheiten erforderlich durch die Routine verwendet, kann die Routine nicht inlined werden. Wenn dies geschieht, gibt den Compiler einen Hinweis wie diese

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

Um das Problem zu beheben, fügen Sie die uses-Klausel Aufrufort die fehlende Einheit Namen.

9

Inline-Funktionen können inline erweitert werden. Zum Beispiel:

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. 

neu geschrieben:

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

Diese den Aufwand für einen Funktionsaufruf entfernt.

Aber um den Aufruf mit dem Funktionskörper zu ersetzen, benötigt der Compiler mehr Informationen, daher die Beschwerde über das Gerät.

Beachten Sie, dass nicht alle Inline-Funktionen konvertiert werden. Einige werden wie normale Funktionen behandelt (es ist der Compiler). Außerdem wird Inline nur bei sehr engen Leistungsengpässen benötigt.

0

Inline-Funktionen werden an Ort und Stelle durch den Compiler erweitert, den Overhead eines Funktionsaufrufs zu vermeiden. Z.B.Zum Quadrieren wird sqr (x) als x * x kompiliert, anstatt eine Funktion aufzurufen, die x multipliziert und das Ergebnis zurückgibt.

6

Ich war auch durch diesen Hinweis verwirrt. Dann wurde mir klar, was das Problem ist. Ihr Code:

uses 
    SysUtils; 

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

wahrsten Sinne des Wortes wird mit Fassung:

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; 

Wenn Sie bemerken, Ihre "neuen" Code ist abhängig von WinApi.Windows Einheit:

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

die Sie nicht in Ihrer uses Klausel enthalten.

Wenn Sie den Code manuell eingefügt (kopiert und eingefügt) haben, wird der Code nicht kompiliert, bis Sie Windows zu Ihrem uses hinzugefügt haben.

Stattdessen wird der Compiler nicht die inline weil:

Inline-Funktion 'DeleteFile' erweitert wurde nicht, weil Unit 'Windows' angegeben ist nicht in uses-Liste "

+3

" ist wörtlich ersetzt werden mit "- nicht GENAU, wie Sie es gezeigt haben, weil der Inlining-Prozess Anpassungen vornehmen muss, um die Parameter und Ergebniswerte für einen Funktionsaufruf, der nicht mehr ein Funktionsaufruf nach Inlining ist, angewendet wird. Aber die Jist Ihrer Antwort ist Korrekt - der Code innerhalb von 'SysUtils.DeleteFile()' wird in die aufrufende Firma gebracht de, und es erfordert einen Verweis auf die "Windows" -Einheit, um die API-Aufrufe zu erfüllen, sonst könnte das Inlining nicht kompiliert werden. –