2011-08-09 5 views
8

私はそのクラスの中で使われていないprivateメソッドはコンパイラ/リンカによって削除され、最終的なバイナリの一部ではないと考えました。最後のバイナリから未使用のメソッドを除外する方法は?

実装されていますが使用されていないプライベートメソッドを使用して、サンプルクラスを作成しました。

class XXX 
{ 
    public: 
    XXX(); 

    private: 
    void MyUnusedMethod(); 
}; 

と実装ファイルで

void XXX::MyUnusedMethod() 
{ 
    const char* hugo = "ABCCHARLYABC"; 
    printf(hugo); 
} 

は、コンパイル後の文字列は、まだ最終バイナリに存在します。どうして?そして、どうすればこれを防ぐことができますか?

敬具、 チャーリー

+0

なぜ、その方法を '#if 0 ... #endif'ブロックに入れることができないのですか? – iammilind

+0

gccの最適化フラグを調整しようとしましたか? – slaphappy

+0

あなたが '-O3'フラグを意味するならば、それは違いはありません。もちろん、もし私がもう使用しないことを知っていれば、私はそれを削除するのが面倒ではありません。しかし、それはまた、一般的な質問です:なぜそれはコンパイラ/リンカーによって落とされませんか? – Charly

答えて

7

移植性のある方法の1つは、各機能ごとに.oファイルを用意することです。その後、それらの.oファイルからアーカイブ.aをビルドします。そのアーカイブにリンクするとき、リンカーはシンボルを解決する.oファイル、つまり誰も呼び出さない関数を持つ.oファイルのみをリンクします。link-time code generationで最新バージョンのgccを使用することもできます。

+1

リンクタイムコード生成のための+1、これは私にとって理想的な解決策です! – Veger

1

これはおそらく、本当に悪い考えですが、私はとにかくそれを記述する必要があり:)あなたはテンプレートクラスを作成することができ、AFAIR未使用の方法が削除されます。

+0

ええ?本当に? afaik、任意のインスタンス化は、すべてのコードを持っています.. – Nim

+0

私は本当に確かめるためにそれを確認する必要があります、私はどこかでそれを読んだと思った。手元にテンプレートブックがありません:/ – duedl0r

+0

答えは正しいです。その根拠は 'class Foo 'はすべてのメソッドが 'T'のすべての値に対してコンパイルされない場合でも有用であるということです。例えば。 'T == const int'は' Foo 'の非constメソッドをすべて破ります。 – MSalters

3

コンパイル後、文字列はまだ最終バイナリに存在します。理由

他の人は、最終的なバイナリでその未使用コードを取り除く方法を提案しました。私はWhyで答えを出したいのですが、ここでは2つの理由があります。なぜなら、その関数を削除することは不可能かもしれないからです。

あなたはstatic linkageとそのXXXタイプのすべてのオブジェクトを宣言しない限り、他のいくつかのオブジェクトファイルがexternを使用して値にアクセスする可能性があるため、コンパイラが生成したオブジェクトファイルからタイプ(ひいては法)を取り除くことはできません。一度にすべてのオブジェクトファイルを見ることができるリンカは、これを解決することができます。

質問にはgccと表示されているため、-fvisibility=hiddenとコンパイルまたはリンクしていない可能性があります。その場合、実行時に他のモジュールがシンボルを解決する可能性があるため、リンカでさえシンボル(したがってコード)を削除することはできません。

+0

"(従ってその方法)"は前提に従わない。オブジェクトの数にかかわらず、 'MyUnusedMethod'に何の呼び出しもない場合、バイナリにする必要はありません。 – MSalters

+0

@MSalters:最終モジュール(例えば共有ライブラリの実行可能ファイル)に 'MyUnusedMethod 'のシンボルが省略されていない場合、他のモジュールが実行時にシンボルを解決してアクセスすることがあります。モジュール内で使用されていないコードは、モジュール内にとどまります。共有ライブラリによって公開されている関数を考えてください。 –

7

これは通常、-functions-sections -fdata-sectionsのオプションをgccに渡すことによって行われます。詳細はlinkをご覧ください。

関連する問題