1

我正在使用 Xcode 构建一个 C++ 项目。

但我不明白错误信息:

“Apple Mach-O 链接器命令失败,退出代码为 1”

我发现#include 是原因。

我有两个 .cpp 文件,其中包含一个相同的 .h 文件。如果我删除#include of one,它将成功构建。

其他头文件都很好,除了上面描述的头文件。我已经使用了“ifndef”。

4

1 回答 1

3

#ifndef包含守卫仅在翻译单元级别(通常是单个源文件)起作用。

如果您在两个翻译单元中定义相同的对象两次,则包含保护不会解决此问题,但是当您尝试将两个对象文件组合成一个可执行文件时,链接器会抱怨。

我怀疑你的情况类似于:

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; }

在这种情况下,include 守卫将防止标头被包含在两次中,prog1.c但它仍然会被包含在两者中prog1.c prog2.c这意味着每个都会有一个xyzzy.

当您将它们链接在一起时,链接器将不喜欢那样。

解决方案是不在头文件中定义东西,而只是在那里声明它们,将定义留给 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; }

声明是诸如函数原型、外部变量、类型定义等之类的东西(简单地说,声明某事物的事物存在而不实际创建“对象”)。

定义是创建“对象”的事物,例如非外部变量等。

您需要跟踪定义了两次的“对象”(链接器输出应该有类似的东西doubly-defined symbol 'xyzzy'),然后确保它没有在标题中定义。

于 2013-04-24T02:53:40.210 回答