質問

私はC ++プログラムで作業しており、1200行の単一ファイル(かなり複雑な状態マシンを初期化する)からコンパイルされたオブジェクトコードがほぼ1メガバイトになります。ファイルを非常に大きくすることができますか?オブジェクトファイル内でスペースが必要なものを見つける方法はありますか?

役に立ちましたか?

解決

オブジェクトファイルが必要以上に大きい場合、いくつかの理由が考えられます。

  • 依存ライブラリを静的に含める
  • デバッグ情報を使用した構築
  • プロファイリング情報を使用した構築
  • テンプレートを使用して(非常に)複雑なデータ構造を作成する(おそらく再帰的なブースト構造)
  • コンパイル中に最適化フラグを有効にしない(あまり保存しないため、あまりにも使用すると問題が発生する可能性があります)

最初に、デバッグ情報を使用してビルドしているかどうかを確認することをお勧めします。これにより、私の経験上最も膨れ上がります。

他のヒント

(最適化とデッドコードストリッピングが有効になっていると仮定しています)

リンカーの<!> quot;マップファイルの生成<!> quot;オプションを選択し、出力を調べます。

よくある犯人は、大量のコードと大規模なグローバルオブジェクトを生成するマクロ/テンプレートです。

おそらく、いくつかのテンプレートのインスタンス化(特にstd::iostream s)、および大規模なインライン展開(つまり、ヘッダーで完全に定義されたクラス)。ただし、そもそも1メガバイトのオブジェクトファイルの問題は何ですか?リンク中に、非常に小さなバイナリになる可能性があります。ここでは、たとえば700 KiBのバイナリにリンクされる20 MiBのオブジェクトファイルを含むプロジェクトを取得しました。

更新:いくつかの大きな静的配列/オブジェクトでもある可能性があります。それに加えて、MSVC ++およびGCCでは、ファイルの生成されたアセンブリを見ることができ、いくつかのヒントを得ることができます(GCCではg++ -S foo.cpp、MSVC ++では '/ FAs' )。多数のテンプレートインスタンスが表示されるか、これらが理由です。そうでない場合は、staticオブジェクトのオブジェクトサイズです。

別の考えられる理由は、VC ++オプションであるリンク時コード生成です。これにより、コンパイラのバックエンドがリンカーに移動します。これにより最適化が改善されますが、オブジェクトファイルには通常、フロントエンドとバックエンドの間で渡されるすべての内部データ構造を含める必要があります。

コンパイル時の値を確認するために使用するマクロは次のとおりです。

template <size_t N> struct compile_time_number { private: typedef int check; };
#define compiler_check_number(N) ((compile_time_number< N >::check)0)

その後、コンパイル時に喜んでどのシンボルがスペースを占有しているかを確認します。

編集:誰もこれを理解していないようですので、明確にします。これを使用する方法はcompiler_check_number(sizeof(<insert struct or global variable here>))を追加することです。コンパイラーは、変数または構造体のサイズをコンパイル時エラーとして吐き出します。コードが巨大なオブジェクトファイルの理由になることはほとんどありません。

私はこれを常に使用して、デバッガーを実行せずにどれだけ大きなものかを確認します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top