2

コードをリンクするときに表示される動作を説明できません。多分誰かが何が起こっているのか考えている...

ビルドシステムとしてGNUautomakeツールを使用する複数ファイルのC++プロジェクトがあります(すべてLinux上)。

util.ccソースファイルとヘッダーファイル(とを呼び出しますutil.h)をプロジェクトに追加し、既存のソースファイル( )が新しく追加されたファイルから関数を呼び出すようにした後、ステートメントが表示calc.ccされる場所に応じてリンクエラーが発生します。include繰り返します:リンクステップでエラーが発生し、コンパイルは正常に実行されます!!

例:

新しいincludeステートメントを既存のステートメントの最後に置くと、次のようなエラーが発生します。

calc.cc:

#include "file1.h"
#include "file2.h"
#include "file3.h"
#include "file4.h"
#include "util.h"   // new header

このバージョンは正常にコンパイルされます。しかし、リンクするとエラーが発生します(シンボルが見つかりません)!!

さて、これをに変更すると

#include "util.h"   // new header
#include "file1.h"
#include "file2.h"
#include "file3.h"
#include "file4.h"

その後、コンパイルとリンクは正常に実行されます。

リンカは.oファイルを読み取るだけなので、これは、includeステートメントが表示される場所に応じて異なるコンテンツが生成されることを意味する必要があります。どうすればいいの?

コンパイラはg++(GCC)4.4.6です

4

3 に答える 3

1

単純なヘッダーファイルは、マクロを(再)定義して、後のマクロの解釈を変更することができます。

たとえば、上記の例では、file1.hが

#define lseek lseek64

util.hにはlseekを呼び出すインライン関数があり、インクルードの順序に応じて、生成されたオブジェクトコードにはlseekまたはlseek64へのシンボル参照があります。

これが、プロジェクトにconfig.h(autoconfによって生成された)が最初に含まれるルールがある傾向がある理由です。

于 2012-07-20T10:32:54.443 に答える
1

util.h には、他のファイルの 1 つの動作を変更する #define が含まれている可能性があります。

何が起こっているのかを正確に理解する最善の方法は、欠落しているシンボルの名前についてこれらのヘッダー ファイルを調べ、「動作する」方法と「動作しない」方法の両方で calc.cc をコンパイルしてプリプロセッサの出力を取得することです。 2 つのファイル。

于 2012-07-20T10:30:08.843 に答える
0

あなたは絶対に正しいです:2つのケースで異なるオブジェクトコードが生成されます。@hmjdも指摘しているように、util.hには、他の(.hまたは.c)ファイルの1つが使用するマクロがあり、宣言されていない、呼び出された識別子はコンパイラによって関数であると見なされます。これはここでエラーが発生する可能性があります。

于 2012-07-20T10:34:40.527 に答える