Подсказка компилятора: "Встроенная функция '...' не была расширена ..." - PullRequest
14 голосов
/ 16 марта 2009

В блоке я использую функцию DeleteFile и компилятор выводит подсказку:

"H2443 Встроенная функция« DeleteFile »не была расширена, так как модуль« Windows »не указан в списке USES»

В Uses есть SysUtils, который определяет DeleteFile (хотя для внутреннего вызова Windows.DeleteFile).

Что означает этот намек? Если я добавлю Windows в предложение Uses, оно исчезнет, ​​но я хотел бы понять, что беспокоит компилятор.

Ответы [ 4 ]

24 голосов
/ 16 марта 2009

Это встроенное ограничение.

См. Статью Халварда Вассботна о Встроенных процедурах .

Извлечено с этого сайта:

Остальные встраиваемые ограничения являются общими для обеих платформ и самые важные из них

  • нет встраивания через границы пакета
  • встроенная подпрограмма не может получить доступ к идентификаторам секций реализации
  • сайт вызова должен иметь доступ ко всем идентификаторам, используемым во встроенном рутина

Примечание Последний пункт означает, что, если блок узла вызова не использует единицы, требуемые процедурой, процедура не может быть встроенной. Когда это происходит, компилятор выдает подсказку, подобную этой

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

Чтобы решить эту проблему, добавьте отсутствующее имя устройства в раздел об использовании сайта вызова.

11 голосов
/ 16 марта 2009

Встроенные функции могут быть расширены встроенными. Например:

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.

Это устраняет накладные расходы при вызове функции.

Но для того, чтобы заменить вызов телом функции, компилятору требуется больше информации, а значит, и жалоба на модуль.

Помните, что не все встроенные функции преобразуются. Некоторые обрабатываются как обычные функции (зависит от компилятора). Кроме того, встраивание требуется только при очень узких узких местах производительности.

7 голосов
/ 19 августа 2014

Меня тоже смутил этот намек. Тогда я понял, в чем проблема. Ваш код:

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;

Если вы заметите, ваш «новый» код зависит от WinApi.Windows единицы:

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

, который вы не включили в ваше предложение uses.

Если вы вручную ввели код (скопировал и вставил), код просто не скомпилируется, пока вы не добавите Windows к вашему uses.

Вместо этого компилятор не будет делать inline, потому что:

Встроенная функция «DeleteFile» не была расширена, поскольку модуль «Windows» не указан в списке «ИСПОЛЬЗОВАНИЕ» «

1 голос
/ 16 марта 2009

Встроенные функции расширяются на месте компилятором, избегая накладных расходов при вызове функции. Например. для возведения в квадрат sqr (x) компилируется как x * x вместо вызова функции, которая умножает x и возвращает результат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...