开发者

How Delphi Compiles my code

How will the Delphi compiler compiles the following code ;

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)

en开发者_运维技巧d;

in this code true = false will never happen so component acompont will never created .

when delphi is compiling in optimized mode will these unused units and code are omitted

AND WHEN using units

in delphi 7 , even if you just uses XPMan unit; (without using any components it has(TXPManifest1)) , still the unit is used and every components are shown with theme ;

and some said Delphi will omit units if it is not needed ;

So how Delphi identifies whether a unit has an impact on the unit it calls or not


See for yourself: Compile the code and run it in the debugger. You won't be able to set a breakpoint on any statements inside the if false then block, and you won't be able to set any breakpoints in the constructor of the Tbig_component class in the other unit. Why? Because there isn't any code for these statements.

You can also view the machine code generated by the compiler by opening the Disassembly view in the IDE. It will show the machine code for each source line. You'll find there will be no machine code generated for the if false then block.


Read this paragraph. Since your conditional expression going to be resolved at compile time, optimizer will throw away any statements under then. Entire unit, however, will not be excluded.


I have made some test using TTable component in 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.

Executable size = 820736 bytes.

Now I have changed the above code a little:

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

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

Executable size = 844288 bytes.

So Delphi linker is smart enough to eliminate about 24K of the dead TTable code.


I cannot check here because it's years I'm not using delphi anymore, but I expect the unit to be compiled and included, because after all they are present in the code. But there will be no code to call them (at least there). A conditional $IF instead should do the trick.


The Delphi compiler is smart enough to remove code that is not used. However units that are used can still add size to the final executable even if your code does not directly reference the content of the unit.

If the unit has got a initialization-section then all code that is referenced in the section will be included.

If the unit has got linked resources (like the XPMan-unit) then those resources will be included in your exe-file too.

To make absolutely sure that a unit is excluded when you want it to you will need to use conditional directives like this:

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

In the example above usebigcomponent is defined in "Conditinal defines" in Project Options or by using a {$define} directive. When usebigcomponent is not defined the unit will be excluded. Conditional directives will make your code harder to read so it's up to you whether you think its worth it for the smaller executable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜