Как Delphi компилирует мой код - PullRequest
0 голосов
/ 04 декабря 2010

Как компилятор Delphi скомпилирует следующий код;

uses a_big_unit;


procedure TForm1.Button1Click(Sender: TObject);
var
acompont : T_a_big_component ;
begin

if (true = false ) then // or            if false then
begin
  bc :=  Tbig_component.create(self)

end;

в этом коде true = false никогда не произойдет, поэтому компонент acompont никогда не будет создан.

при компиляции delphi в оптимизированном режиме эти неиспользуемые модули и код будут пропущены

И КОГДА используйте единицы

в Delphi 7, даже если вы просто используете единицы XPMan;(без использования каких-либо компонентов, которые у него есть (TXPManifest1)), все еще блок используется, и все компоненты показаны с темой;

и некоторые сказали, что Delphi пропустит юниты, если в этом нет необходимости;

Так как Delphi определяет, влияет ли юнит на юнит, который он вызывает, или нет

Ответы [ 5 ]

6 голосов
/ 04 декабря 2010

Убедитесь сами: скомпилируйте код и запустите его в отладчике.Вы не сможете установить точку останова для каких-либо операторов внутри блока if false then, и вы не сможете установить любые точки останова в конструкторе класса Tbig_component в другом модуле.Зачем?Поскольку для этих операторов нет никакого кода.

Вы также можете просмотреть машинный код, сгенерированный компилятором, открыв представление Разборка в IDE.Он покажет машинный код для каждой исходной строки.Вы обнаружите, что для блока if false then не будет создан машинный код.

1 голос
/ 04 декабря 2010

Читать этот абзац .Поскольку ваше условное выражение будет разрешено во время компиляции, оптимизатор отбросит все операторы в then.Вся единица, однако, не будет исключена.

1 голос
/ 04 декабря 2010

Я провел некоторый тест с использованием компонента TTable в Delphi 2009:

1)

unit Unit5;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, DBTables, StdCtrls;

type
  TForm5 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form5: TForm5;

implementation

{$R *.dfm}

procedure TForm5.Button1Click(Sender: TObject);
var
  T: TTable;

begin
  if False then
    T:= TTable.Create(nil);
end;

end.

Размер исполняемого файла = 820736 байт.

Теперь я немного изменил приведенный выше код:

procedure TForm5.Button1Click(Sender: TObject);
var
  T: TTable;

begin
  if True then
    T:= TTable.Create(nil);
end;

Размер исполняемого файла = 844288 байт.

Итак, компоновщик Delphi достаточно умен, чтобы исключить около 24K мертвого кода TTable.

0 голосов
/ 05 декабря 2010

Компилятор Delphi достаточно умен, чтобы удалить неиспользуемый код. Однако используемые модули могут по-прежнему увеличивать размер конечного исполняемого файла, даже если ваш код напрямую не ссылается на содержимое модуля.

Если устройство имеет -секцию инициализации , тогда будет включен весь код, указанный в разделе.

Если устройство имеет связанных ресурсов (например, XPMan-модуль), то эти ресурсы также будут включены в ваш exe-файл.

Чтобы быть абсолютно уверенным, что юнит исключен, когда вы этого хотите, вам нужно будет использовать условные директивы, подобные этому:

uses 
  {$ifdef usebigcomponent}
  BigUnit,
  {$endif} 
  SysUils;

В приведенном выше примере usebigcomponent определяется в «Условных определениях» в параметрах проекта или с помощью директивы {$ define}. Когда usebigcomponent не определен, единица будет исключена. Условные директивы затруднят чтение вашего кода, поэтому вам решать, считаете ли вы, что оно того стоит для меньшего исполняемого файла.

0 голосов
/ 04 декабря 2010

Я не могу проверить здесь, потому что это годы, я больше не использую Delphi, но я ожидаю, что модуль будет скомпилирован и включен, потому что в конце концов они присутствуют в коде. Но не будет кода для их вызова (по крайней мере, там). Вместо этого следует использовать условный $ IF.

...