web-dev-qa-db-ja.com

複数の定義...リンカーエラー

特別なファイルを定義しました:config.h

私のプロジェクトにはファイルもあります:

t.c, t.h
pp.c, pp.h
b.c b.h
l.cpp

および#includes:

in t.c:

    #include "t.h"
    #include "b.h"
    #include "pp.h"
    #include "config.h"

b.c:

    #include "b.h"
    #include "pp.h"

in pp.c:

    #include "pp.h"
    #include "config.h"

in l.cpp:

    #include "pp.h"
    #include "t.h"
    #include "config.h"

*.hファイルにはincludeディレクティブがありません。*.cファイルにのみ含まれます。これをconfig.hで定義しました:

const char *names[i] =
        {
            "brian", "stefan", "steve"
        };

l.cpp、t.c、pp.cでその配列が必要ですが、私はこのエラーを取得しています:

pp.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
t.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [link] Error 1

プロジェクトで使用するすべての*.hファイルにガードを含めています。これを解決する助けはありますか?

40
mazix

ヘッダーに変数を定義しないでください。宣言をヘッダーに、定義を.cファイルの1つに入れます。

Config.hで

extern const char *names[];

一部の.cファイル:

const char *names[] =
    {
        "brian", "stefan", "steve"
    };

ヘッダーファイルにグローバル変数の定義を配置すると、この定義はこのヘッダーを含むすべての.cファイルに移動します。変数は複数回宣言できますが、一度しか定義できないため、複数の定義エラーが発生します。 。

96
Yu Hao

パブリック関数の宣言はヘッダーファイルに含まれています。ただし、ヘッダーでも定義は完全に有効です。各cファイルで再度定義する必要のないユーティリティ関数のヘッダーで定義する場合、定義を静的(プログラム全体で1つのコピーのみ許可)として宣言できます。 I.E.列挙と静的関数を定義して、列挙を文字列に変換します。その後、ヘッダーを含む各.cファイルの列挙型を文字列変換プログラムに書き換える必要はありません。 :)

25