1

Xcode を使用して C++ プロジェクトをビルドしています。

しかし、私はエラーメッセージを理解していません:

「Apple Mach-O リンカ コマンドが終了コード 1 で失敗しました」

#include が理由であることがわかりました。

同じ .h ファイルを含む 2 つの .cpp ファイルがあります。1 つの #include を削除すると、正常にビルドされます。

上記のヘッダー ファイルを除いて、他のヘッダー ファイルは問題ありません。私はすでに「ifndef」を使用しました。

4

1 に答える 1

3

#ifndefインクルード ガードは、翻訳単位 (通常は単一のソース ファイル) のレベルでのみ機能します。

2 つの翻訳単位で同じオブジェクトを 2 回定義すると、インクルード ガードでは修正されませんが、2 つのオブジェクト ファイルを 1 つの実行可能ファイルに結合しようとすると、リンカは激しく文句を言います。

あなたの状況は次のようなものだと思います:

hdr.h:
    #ifndef HDR_H
        #define HDR_H
        void rc(void);
        int xyzzy;
    #endif

prog1.c:
    #include "hdr.h"
    #include "hdr.h"
    int main (void) { rc(); return xyzzy; }

prog2.c:
    #include "hdr.h"
    void rc(void) { xyzzy = 0; }

そのような状況では、インクルード ガードはヘッダーが に 2 回インクルードされるのを防ぎますが、prog1.cの両方にインクルードされます。つまり、それぞれに のコピーが含まれます。prog1.c prog2.cxyzzy

それらを一緒にリンクすると、リンカーはそれを好まないでしょう。

解決策は、ヘッダーで何かを定義するのではなく、ヘッダーで宣言するだけで、C ファイルの定義を残すことです。

hdr.h:
    #ifndef HDR_H
        #define HDR_H
        int rc(void);
        extern int xyzzy;              // declare, not define
    #endif

prog1.c:
    #include "hdr.h"
    #include "hdr.h"
    int main (void) { rc(); return xyzzy; }

prog2.c:
    #include "hdr.h"
    int xyzzy;                         // define
    int rc(void) { xyzzy = 0; }

宣言とは、関数プロトタイプ、extern 変数、typedef などのようなものです (簡単に言うと、実際に「オブジェクト」を作成せずに何かが存在することを宣言するものです)。

定義とは、非 extern 変数などの「オブジェクト」を作成するものです。

どの「オブジェクト」が 2 回定義されているかを追跡する必要があります (リンカーの出力には のようなものがあるはずです)。次に、それがヘッダーで定義さdoubly-defined symbol 'xyzzy'れていないことを確認します。

于 2013-04-24T02:53:40.210 に答える