2009-03-16 19 views
14

En una unidad utilizo la función DeleteFile y el compilador emite una pista:Compilador Consejo: "función en línea '...' no se ha ampliado ..."

"función H2443 Inline 'DeleteFile' no se ha ampliado debido a la unidad de 'Windows' no se especifica en la lista de usos"

en Uses hay SysUtils, que define DeleteFile (aunque internamente llamando Windows.DeleteFile).

¿Qué significa esta pista? Si pongo Windows en la cláusula Uses, ya no está, pero me gustaría entender qué es lo que molesta al compilador.

Respuesta

23

Es una restricción de entrada.

Vea el artículo de Hallvard Vassbotn sobre Inlined Routines.

Extraído de ese sitio:

El resto de las restricciones Inlining son comunes para ambas plataformas y los los más importantes son

  • hay procesos en línea a través de los límites del paquete
  • la inlined la rutina no puede acceder a los identificadores de la sección de implementación
  • el sitio de la llamada debe tener acceso a todos los identificadores rs utilizados en la rutina de inline

Nota El último punto significa que a menos que la unidad de sitio llamada utiliza las unidades requeridas por la rutina, la rutina puede no ser inline. Cuando esto sucede, el compilador emite una pista como esta

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

Para resolver el problema, agregue el nombre de la unidad que falta a la cláusula usos del sitio llamada.

9

Las funciones en línea se pueden ampliar en línea. Por ejemplo:

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. 

se vuelve a escribir a:

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

Esto elimina la sobrecarga de una llamada a la función.

Pero para reemplazar la llamada con el cuerpo de la función, el compilador necesita más información, de ahí la queja sobre la unidad.

Tenga en cuenta que no todas las funciones en línea se convierten. Algunos se tratan como funciones normales (depende del compilador). Además, en línea solo se necesita en cuellos de botella de rendimiento muy ajustado.

0

funciones en línea se expanden en su lugar por el compilador, evitando la sobrecarga de una llamada a la función. P.ej.para cuadrar, sqr (x) se compila como x * x en lugar de llamar a una función que multiplica x y devuelve el resultado.

6

Esta sugerencia también me confundió. Entonces me di cuenta de lo que es el problema. Su código:

uses 
    SysUtils; 

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

, literalmente, está siendo reemplazado con:

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; 

Si te fijas, su "nueva" código depende de WinApi.Windows unidad:

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

que se no se incluyó en su uses cláusula.

Si ha introducido manualmente el código (copiado y pegado), el código simplemente no se compilará hasta que haya agregado Windows a su uses.

En su lugar, el compilador no hará el inline porque:

función

Inline 'DeleteFile' no se ha ampliado debido a la unidad de 'Windows' no se especifica en la lista de "

+3

" usos es, literalmente, siendo reemplazado por "- no EXACTAMENTE como lo mostró, porque el proceso de alineación tiene que hacer ajustes para manejar los parámetros y los valores de Resultado para una llamada de función que ya no es una llamada de función después de aplicar la inserción. Pero la respuesta es correcto: el código dentro de 'SysUtils.DeleteFile()' se está llevando a la co de llamada de, y requiere una referencia a la unidad 'Windows' para satisfacer las llamadas API o de lo contrario no se compilará la línea entrante. –

Cuestiones relacionadas