Delphi如何编译我的代码

时间:2010-12-04 14:21:53

标签: delphi optimization compiler-construction code-generation

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如何识别一个单位是否对其所调用的单位产生影响

5 个答案:

答案 0 :(得分:6)

自己看看:编译代码并在调试器中运行它。您将无法在if false then块内的任何语句上设置断点,并且您将无法在另一个单元中的Tbig_component类的构造函数中设置任何断点。为什么?因为这些陈述没有任何代码。

您还可以通过在IDE中打开“反汇编”视图来查看编译器生成的机器代码。它将显示每个源代码行的机器代码。您会发现没有为if false then块生成机器代码。

答案 1 :(得分:1)

阅读this paragraph。由于条件表达式将在编译时解析,优化器将丢弃then下的任何语句。但是,不排除整个单元。

答案 2 :(得分:1)

我在Delphi 2009中使用TTable组件进行了一些测试:

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代码。

答案 3 :(得分:0)

我无法在这里查看,因为多年来我不再使用delphi,但我希望编译和包含该单元,因为它们毕竟存在于代码中。但是没有代码可以调用它们(至少在那里)。 有条件的$ IF应该可以做到这一点。

答案 4 :(得分:0)

Delphi编译器非常智能,可以删除未使用的代码。但是,即使您的代码没有直接引用该单元的内容,使用的单元仍然可以为最终的可执行文件添加大小。

如果该单元有初始化 - 部分,那么将包含该部分中引用的所有代码。

如果该单元有链接资源(如XPMan单元),那么这些资源也将包含在您的exe文件中。

要确保在您需要时排除某个单位,您需要使用这样的条件指令:

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

在上面的示例中, usebigcomponent 在“项目选项”的“条件定义”中定义,或者使用{$ define}指令定义。如果未定义usebigcomponent,则将排除该单位。条件指令会使您的代码更难以阅读,因此您是否认为它对于较小的可执行文件是值得的。