Vibeeshan Mahadeva
Vibeeshan Mahadeva

Reputation: 7248

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)

end;

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

Upvotes: 0

Views: 730

Answers (5)

Ville Krumlinde
Ville Krumlinde

Reputation: 7131

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.

Upvotes: 0

dthorpe
dthorpe

Reputation: 36082

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.

Upvotes: 6

kludg
kludg

Reputation: 27493

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.

Upvotes: 1

Free Consulting
Free Consulting

Reputation: 4412

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.

Upvotes: 1

Uberto
Uberto

Reputation: 2712

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.

Upvotes: 0

Related Questions