62

複数の *.c ソース ファイルに含まれるヘッダー ファイル xh があります。このヘッダー ファイルには、いくつかの構造変数が定義されています。

次のように、ヘッダー ファイルの先頭に複数の包含防止ガードを配置しました。

#ifndef X_H
#define X_H
...
..
//header file declarations and definitons.


#endif//X_H

ビルド時に、複数の定義に関連するリンカー エラーが発生します。私は問題を理解しています。

  1. 私が持っているように、ヘッダー ファイルの上部にある複数のインクルージョン防止ガードは、ヘッダー ファイル xh の複数のインクルードを防ぎ、それによって xh にある変数の複数の定義を回避しませんか?

  2. #pragmaこの特定のコンパイラでは一度は機能しません。解決策は何ですか? 誰かがこの回答を同様の質問に投稿しました。私にはうまくいかないようです。このソリューションはどのように機能しますか?

4

6 に答える 6

82

リンカーが不平を言っている場合は、ヘッダーに単なる宣言ではなく定義があることを意味します。間違っていることの例を次に示します。

#ifndef X_H
#define X_H

int myFunc()
{
  return 42; // Wrong! definition in header.
}

int myVar; // Wrong! definition in header.

#endif

次のように、これをソース ファイルとヘッダー ファイルに分割する必要があります。

ヘッダ:

#ifndef X_H
#define X_H

extern int myFunc();

extern int myVar; 

#endif

C ソース:

int myFunc()
{
  return 42; 
}

int myVar; 
于 2008-10-30T10:15:11.377 に答える
21

ヘッダー ガードは、単一のコンパイル単位、つまりソース ファイルに対してのみ有効です。ヘッダー ファイルを複数回インクルードする場合は、おそらく からインクルードされたすべてのヘッダーmain.cが順番にインクルードされているためstdio.h、ガードが役立ちます。

とによって含まれる関数の定義があるf場合、作成時にの定義をにコピーして貼り付け、を作成するために同じことを行うようなものです。次に、リンカーが文句を言い、これはヘッダーガードにもかかわらず発生します。もちろん、これらのガードにより、複数のステートメントを含めることができます。x.hmain.cutil.cfmain.cmain.outil.cutil.o#include "x.h"main.c

于 2012-03-06T00:24:13.870 に答える
15

インクルード ガードを使用すると、1 つのコンパイル ユニットがヘッダーを 2 回インクルードするのを防ぐことができます。たとえば、ヘッダー Bh に Ah が含まれ、B.cpp に Ah と Bh が含まれている場合、インクルード ガードを使用していなければ、Ah からのすべてがコンパイル B.cpp で 2 回宣言されます。

あなたのインクルードガードはこれが起こらないようにします。今まではすべて問題ありません。

しかし、リンク時に複数の定義を取得します。つまり、2 つのコンパイル ユニットが同じものを定義します。これはおそらく、ヘッダーに実際の定義があることを意味し、すべての変数に extern を使用し、関数がインラインか cpp ファイルで定義されていることを確認します。

于 2008-10-30T10:01:32.527 に答える
12

関数が大きくない場合は、それらの前に「インライン」を使用でき、リンカーは文句を言いません。

于 2010-07-16T23:05:26.360 に答える
2

複数の包含ガードを使用すると、コンパイラエラーは回避されますが、リンカー エラーが発生します。ヘッダー ファイルに を使用しないデータ定義がありますexternか?

于 2008-10-30T09:56:16.483 に答える
0

たぶんX_H、すでにどこかで定義されていますか?X_HXlibが /usr/include/X11/Xh で定義されているこの問題に遭遇しました

確認するには、(gcc を使用している場合) を呼び出すことができますgcc -dM -E。たとえば、私が使用しているビルドシステムで動作しCC=gcc CFLAGS="-dM -E" makeます。#define X_Hファイルから削除しても (Y_Hたとえば使用して)、出力ファイルに含まれている場合は、ソース コードの外部で既に定義されています。

于 2012-09-21T13:35:24.830 に答える