web-dev-qa-db-ja.com

「の複数定義」C ++コンパイラエラー

私のクラスの1つでこれらのランダムに見えるコンパイルエラーを取り除くことができないようです。次のような約4つのエラーが発生します。

multiple definition of `draw_line(float, float, float, float)'

そして

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

メソッドの途中でフラグが立てられる。

私も一貫してmultiple definition of `stack'別のメソッドの途中。 stackは、まったく異なるファイル内のグローバル変数です。エラーが発生しているファイルにも記載されていません。

エラーが発生しやすいファイルを.hファイルと.cppファイル(元々は.cppでした)に分けてみましたが、エラーに関する変更は何もありません...

重複するメソッドはありません。 1つだけあります#include of lines.hおよび#ifndef句が最初にあります。これらのエラーはすべて.cppファイルに表示されます。

それが何であるかについての考えはありますか?

さて、私はコードを取得しました:

Lines.cppは、インストラクターから受け取った変換済みの.cファイルです。私はいつも問題があるので、念のためにメイクファイルを含めました。また、ファイル内のエラーがフラグが付けられた場所に正確に注釈を付けましたが、それらはかなりランダムに見えるため、それが特に重要かどうかはわかりません。 .hファイルは何も解決または支援していなかったため、放棄しました。それがなければ間違いを見つけやすくなります。

これが要求された main.cpp file です(.hはありません)。


私はlines.hファイルを作り直しましたが、まだ受け取っています:

multiple definition of `draw_line(float, float, float, float)'

そして

multiple definition of `near_far_clip(float, float, float*, float*, float*, float*, float*, float*)'

lines.cppファイルのエラーですが、multiple definition of `stack'エラーはThreeD.cppファイルのランダムな場所にあります(コメントでマークされています)。 更新:このエラーは修正され、これを示すようにファイルが修正されました:

私はいくつかのグローバル変数にexternというラベルを付けましたが、何も影響を与えていないようでした。

16
Chad

ThreeD.cppに#include lines.cppを含めるのはなぜですか?これは非常に珍しいことです。

Makefileはlines.oを必要とするため、lines.cppをコンパイルします。 lines.cppで定義されたものはすべてlines.oとThreeD.oにもあります。

Lines.cppに興味深いコメントがあります:

Don't forget to put declarations in your .h files. 

インストラクターはlines.cppを.hと.cppに分割してほしいと思います。

Lines.cppからの抜粋:

/* These go in your .h file or in lines.h */
/*

Line drawing header.

*/


void draw_line(float, float, float, float);
int near_far_clip(float, float, float *, float *, float *, float *,
                  float *, float *);

これらの2つの宣言だけがlines.hにあるべきだと思います。

14

ヘッダーファイルに関数定義が含まれている可能性があります。 inlineキーワードを含めて、各オブジェクトファイルによってエクスポートされないようにするか、独自の.cppファイルに入れます。

グローバル変数については、ヘッダーファイルでexternキーワードを使用する必要があります。そうでない場合、各オブジェクトファイルは独自の変数をエクスポートし、リンカはどちらを使用するのが適切かについて混乱します。

34
strager

コードスニペットを投稿してください。たぶん、クラス宣言と外部の両方でメソッドを定義していますか?

class X {
    void foo();    // No definition, just declaration
    void bar() {}  // Declaration + definition
};

void X::foo() {}    // First Definition, OK
void X::bar() {}    // Already defined, ERROR
3
Ferdinand Beyer

スペルミスのガードをチェックしてください。
makeオプションを確認してください。おそらく誰かが複数のオブジェクトファイルにコンパイルされています。
エラーの原因が見つからなくなるまで、ファイルとコードの一部を除外するようにしてください。

編集:
修正には* .cppファイルが含まれます。それらはリンクされるべきです。

3
bayda

言われたように-ここで適切に診断するのに十分な情報がありません。

ただし、draw_line et alがソース(cpp)ファイルではなくヘッダーファイルで定義されている場合、ヘッダーファイルでインラインとして宣言されているメソッドが実際には正しくインライン化されていない可能性があります。その場合、ヘッダーを含む各.cppファイルはdraw_line関数の独自の定義を生成し、リンク時に警告を生成します。

これは、忘れられた、または削除されたシステムヘッダーに由来する#defined INLINEマクロを使用し、何らかの理由でINLINEが前処理されて何もない場合に発生する可能性があります。

例えば。:

//Lines.h

#define GCCC //Note the typo

#if defined(GCC)
#define INLINE inline
#Elif defined (MSVC)
#define INLINE __inline
#else

#define INLINE //Due to the typo, INLINE will be turned into nothing
#endif

INLINE void draw_line(float x1, float y1, float x2, float y2)
{
   //Draw the line
}

//File1.cpp
#include "lines.h" //will define draw_line

//File2.cpp
#include "lines.h" //will also define draw_line

また、File1.cppとFile2.cppをリンクすると、複数の宣言エラーが発生します

3
MrCranky
#ifndef THREED_H_
#define THREED_H_
#endif /* THREED_H_ */

これらの行を削除またはコメントし、これは私のために働いた

2
Gaurav Maan

複数の定義エラーはリンカーエラーですが、詳細情報がないと診断が困難です。リンカーコマンドで同じファイルが2回表示されないこと、およびヘッダーファイルに宣言のみが含まれ、定義が含まれていないことを確認してください。

1
anon

コードを確認しないと、実際には役に立ちません。コンパイラは明らかにあなたの反対を主張します(-is少なくとも1つの重複した定義があります)。

最小限の例でエラーを再現してみてください。コマンドラインでEclipse外のコードをコンパイルしてみましたか?どんな結果で?

1
Konrad Rudolph

こんにちは、llには基本的なルールが適用されるとここで見ます。これらの種類のエラーでどのように機能するかを説明し、それらが来ると次のようになります。例を見てみましょう"Making a global variable"

cppファイルの場合、ヘッダーファイルを混同しないでください。ヘッダーは、複数のファイルプロジェクトがリンクする前に共通のインターフェイスを持つことができるようにするためだけにあります。

1.リストアイテム

ヘッダーでグローバル変数に関する情報を提供する必要があります:

extern int Var_Global;

  1. リストアイテム

    while keeping the Actual code in the
    cpp :
    
    int Var_Global;
    

そして、必ず1.ヘッダーを含め、2。コードをリンクしてください。

コードを1回だけリンクします。データのコピーは1つしかありませんが、ヘッダーを1日中含めることができれば、リンク時にデータのコピーがあることを他のコードに伝えます。

多くの人がコードをヘッダーファイルに配置しているのを見ていますが、場合によってはうまくいくかもしれませんが、中に入るのは悪い習慣であり、遅かれ早かれ問題を引き起こすでしょう。

よろしく、

プラシャンタ