0

Delphiコンパイラはどのようにして次のコードをコンパイルしますか。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が最適化されたモードでコンパイルされたこれらの未使用のユニットとコードがあなただけのXPManユニットを使用している場合でも、

を省略とDelphi 7で単位

を使用してWHENれます。 (それが持っているコンポーネント(TXPManifest1)を使用せず)、それでもユニットが使用され、すべてのコンポーネントがテーマで表示されます。

と言われています。必要がない場合、Delphiは単位を省略します。

だから、Delphiはユニットが、それは私はもうデルファイを使用していない年だから、私はここでチェックすることはできませんが、私はユニットをコンパイルして含まれることを期待呼び出すか

+0

なぜ「falseなら」ですか? –

+3

@Andreas Rejbrand falseの場合は、false = trueであることを意味します。そして私は真実=偽LOLを意味しました! – VibeeshanRC

+0

ちょうどチェックするのはどうですか? if文の前にブレークポイント(たとえば 'asm int 3; end;')を置き、実行してif文がないかどうかを確認します。 – CodesInChaos

答えて

6

参照:コードをコンパイルし、デバッガで実行します。 if false thenブロック内のステートメントにブレークポイントを設定することはできず、他のユニットのTbig_componentクラスのコンストラクターでブレークポイントを設定することはできません。どうして?これらのステートメントのコードは存在しないためです。

コンパイラで生成されたマシンコードは、IDEの逆アセンブリビューを開いて表示することもできます。各ソース行のマシンコードが表示されます。 if false thenブロック用に生成されたマシンコードがないことがわかります。

+0

例外は、bigunitにTbig_componentを参照する初期化ブロックがあり、それがとにかく含まれる場合です。その場合、最小サイズのuses節に$ ifdef bigunitを置く必要があります。 –

+0

XPManを使用していても、a_big_unitは省略されるか、または – VibeeshanRC

+0

がdelphi 7でないことを尋ねました。ユニットは(それが持っているコンポーネントを使用せずに)、ユニットが使用され、すべてのコンポーネントがテーマで表示されます。どのようにデルファイコンパイラが納得のいくようにスマートであるか – VibeeshanRC

0

ユニットに影響を与えるかどうかを識別する方法結局のところ、彼らはコード内に存在するからです。しかし、(少なくともそこに)呼び出すコードはありません。 代わりに、条件付きの$ IFがそのトリックを行うべきです。

1

this paragraphを読んでください。コンパイル時に条件式が解決されるため、オプティマイザはthenの文をすべて破棄します。ただし、ユニット全体が除外されることはありません。私は、Delphi 2009年のTTableコンポーネントを使用して、いくつかのテストを行った

+0

ユニット内のコード(祖先クラスとメタクラスを介したメソッドの実際の使用またはアクセス可能性)によっては、リンカーはそれを捨てる可能性があります。 –

+0

@Marjan Venema:実際はありません。マップファイルを生成して表示します。 –

+1

@ user205376:それはあなたが "捨てる"と呼ぶものに依存します。マップファイルに記述されている唯一の行が**ユニットの '' end.'ステートメントである場合、そのユニットはマップファイルに記述されていますが、私の心には効果的にスローされています。 –

1

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バイト:

は、今私は少し上記のコードを変更しました。

だから、デルファイリンカーは約24Kの死んだTTableコードを除去するのに十分なほどスマートです。

+0

はい、それでもユニットはリンケージです – VibeeshanRC

0

Delphiコンパイラは、使用されていないコードを削除するほどスマートです。ただし、コードがユニットの内容を直接参照していない場合でも、使用されているユニットは最終的な実行ファイルにサイズを追加できます。

ユニットに初期化-sectionsがある場合、そのセクションで参照されているすべてのコードが含まれます。

ユニットにというリンクされたリソース(XPManユニットのようなもの)がある場合、そのリソースもあなたのexeファイルに含まれます。あなたはあなたにそれをしたい時にユニットが除外されていることを絶対に確認するために

は、このような条件付きのディレクティブを使用する必要があります。usebigcomponent上記の例では

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

の中で「Conditinal定義」に定義されていますプロジェクトオプションを使用するか、{$ define}ディレクティブを使用します。 usebigcomponentが定義されていない場合、ユニットは除外されます。条件付きのディレクティブは、コードを読みにくくするため、小さな実行可能ファイルの価値があるかどうかはあなた次第です。

関連する問題