链接器问题与头文件

时间:2016-02-09 20:31:54

标签: c xcode linker

在C应用程序中,我有一个main.c文件:

#include <stdio.h>
#include "foo.h"
#include "bar.h"
int main(int argc, const char * argv[])
{
    foo f;
    bar b;
    return 0;
}

foo.h(和foo.c文件):

#ifndef foo_h
#define foo_h
#include <stdio.h>
#include "bar.h"
#include "utility.h"
typedef struct foo foo;
typedef struct bar bar;
struct foo {
    bar * b;
    int a;
};
#endif

bar.h(和bar.c文件):

#ifndef bar_h
#define bar_h
#include <stdio.h>
#include "foo.h"
typedef struct foo foo;
typedef struct bar bar;
struct bar {
    foo * f;
    int a;
};
int get_b_a(bar b);
#endif

utility.h(没有utility.c):

#ifndef utility_h
#define utility_h
int add(int a, int b);
int add(int a, int b)
{
    return a + b;
}
#endif

然而,这个程序不会在xcode中构建,因为它会抱怨链接器问题: Duplicate symbol _add in bar.o and main.o

我知道我可以通过创建单独的utility.c文件来轻松解决此问题,但我不愿意,因为它会导致较大项目中的文件过多。

解决上述问题的最佳做法是什么?

1 个答案:

答案 0 :(得分:0)

看起来问题是你有太多的包含

你没需要

#include "bar.h"
在foo.h中

,因为你将它包含在main.c中

在编译程序之前,预处理器将结合所有内容...

...所以发生了什么是foo.h的一个副本,bar.h被加载到main中,然后在foo.h和bar.h里面重新加载bar.h和foo.h

所以删除

#include "bar.h"

来自foo.h

并删除

#include "foo.h"
来自bar.h的

它看起来好像你有太多的类型定义

typedef struct foo foo;

这应该只在整个代码中出现一次。

评论后编辑....

你可以在main.c中有一个层次

#include "foo.h"

并且不包括“bar.h”

然后在foo.h中你可以拥有

#include "bar.h"

然后你的程序中只有一个foo.h和bar.h的副本。 (在bar.h中,您不希望有任何#includes)