20

C/C++ でのコンパイルとリンクのプロセスを理解しようとしています。ソース ファイルは、コンパイラによって最初にオブジェクト ファイルに変換されることを知っています。次に、リンカーは、オブジェクト ファイルからライブラリまたは実行可能ファイルを生成しました。

オブジェクトファイルの情報を最初に読み取ろうとしています。ここに私が実験用に書いたプログラムがあります。

func.h

#include <iostream>

void beautifulprint(char *str);

func.cpp

#include "stdafx.h"
#include "func.h"

using namespace std;

void beautifulprint(char *str) {
    cout << "*** " << str << " ***" << endl;
}

TestApp.cpp

#include "stdafx.h"
#include "func.h"

int _tmain(int argc, _TCHAR* argv[])
{
    beautifulprint("Hello, world!");

    return 0;
}

VS 2010 でプロジェクトをビルドした後、func.obj を取得します。func.obj のどこかに、beautifulprint 関数への参照があるはずだと思いました。func.obj のデバッグ バージョンとリリース バージョンの両方に対して以下を実行しました。

dumpbin /HEADERS func.obj > funchead.txt

以下は出力です。

デバッグ バージョン (非常に大きいため、完全な出力は含まれていません)

...

SECTION HEADER #41
   .text name
       0 physical address
       0 virtual address
      78 size of raw data
    5B94 file pointer to raw data (00005B94 to 00005C0B)
    5C0C file pointer to relocation table
       0 file pointer to line numbers
       A number of relocations
       0 number of line numbers
60501020 flags
         Code
         COMDAT; sym= "void __cdecl beautifulprint(char *)" (?beautifulprint@@YAXPAD@Z)
         16 byte align
         Execute Read

SECTION HEADER #42
.debug$S name
       0 physical address
       0 virtual address
      E8 size of raw data
    5C70 file pointer to raw data (00005C70 to 00005D57)
    5D58 file pointer to relocation table
       0 file pointer to line numbers
       7 number of relocations
       0 number of line numbers
42101040 flags
         Initialized Data
         COMDAT (no symbol)
         Discardable
         1 byte align
         Read Only

...

リリース版(完全出力!)

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file func.obj

File Type: ANONYMOUS OBJECT

ANON OBJECT HEADER VALUES
               1 version
             14C machine (x86)
        50213733 time date stamp Tue Aug 07 16:41:39 2012
                 ClassID: {0CB3FE38-D9A5-4DAB-AC9B-D6B6222653C2}
             2D1 size
               0 flags

そして、ここに私の質問があります。予想どおり、func.obj デバッグ バージョンには、beautifulprint への参照があります。しかし、驚いたことに、リリース版には美しいプリントへの言及がありませんか? リンカーは、この関数がオブジェクト ファイルに存在することをどのように認識しますか。

また、デバッグ obj バージョンに iostream の機能があるのはなぜですか? これらは、この obj の代わりに標準ライブラリに存在するべきではありませんか?

編集:リリース func.obj を VS 2010 で 16 進形式で直接開きました。私は美しいプリントを検索し、右側(ASCII)の列にその存在を示しました。参照が存在することを意味します。dumpbin に表示されないのはなぜですか? 人間が読める形式で表示するためのツールが必要です。

4

2 に答える 2

25

代わりにシンボルをダンプしてください。すべての.objファイルにはシンボルテーブルがあります。内部で定義されたシンボルと、解決が必要なシンボルが表示されます。表示されるIOシンボルはUNDEFシンボルである可能性がありますが、シンボルテーブルはそれをより明確にする必要があります。

DUMPBIN /SYMBOLS func.obj

オブジェクトが/GL(プログラム全体の最適化)でコンパイルされている場合、/SYMBOLSは使用できないことに注意してください。/ GL(およびライブラリ)で作成されたオブジェクトモジュールは、あるコンパイラバージョンから次のバージョンへの互換性が保証されていない形式で作成されます。

プログラム全体の最適化とは、オプティマイザーが各モジュール内だけでなく、すべてのモジュールにわたって最適化できることを意味します。関数は「インライン」になる可能性があり、おそらくCOFFとの互換性があまり高くない他のトリックが実行されます。サポートされているすべてのコンパイラバージョンのライブラリを提供する場合を除いて、成果物ライブラリに/GLオプションを設定しないことをお勧めします。

于 2012-08-07T16:15:35.697 に答える