C:架构x86_64的重复符号

时间:2018-11-22 01:32:13

标签: c gcc

我正在尝试在头文件中创建结构,并初始化模板结构。出于某种原因,当将头文件包含在多个文件中时,它给了我以下错误:

gcc foo.c bar.c -o foo -Wall

duplicate symbol _MYFOO in:
    /var/folders/s4/zyw5lgk92wj9ljnsypgwdccr0000gn/T/foo-52f8fc.o
    /var/folders/s4/zyw5lgk92wj9ljnsypgwdccr0000gn/T/bar-6dc21f.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这些是我的文件: Bar.c

#include "bar.h"
#include <stdio.h>

void helloWorld() {
    printf("Hello world\n");
}

Bar.h

typedef struct Foo Foo;

struct Foo {
    int number;
} MYFOO = {2};

void helloWorld(void);

Foo.c

#include "bar.h"

int main() {
    helloWorld();
}

有趣的是,当我删除包含的行

MYFOO = {2};

代码可以编译并正常运行。我认为这与两次包含 Bar.h 有关,而最终两次包含了该结构?但是我该如何避免这样的事情?

谢谢!

2 个答案:

答案 0 :(得分:3)

您可以在Bar.h文件中添加指令,以检查该文件是否已包含:

#ifndef _BAR_H_INCLUDED_
// Bar.h not included - declare your structs, etc, here.

// Define _BAR_H_INCLUDED_ to indicate this file has already
// been included
#define _BAR_H_INCLUDED_ 1
#endif

这至少应该阻止您多次包含Bar.h

编辑

一个更好的解决方案可能是在Bar.c中加入Bar.h

// Bar.h
#ifndef _BAR_C_INCLUDED_

// code here

// Include Bar.c
#include "Bar.c"
#define _BAR_C_INCLUDED_

#endif

然后您可以在Bar.h中简单地包含Foo.c

// Foo.c

#include <stdio.h>
#include <stdlib.h>

#include "Bar.h"

int main() {
    //...

然后编译:

gcc Foo.c -o Foo

所以-这是您更新的代码-首先,Bar.h

#ifndef _BAR_C_INCLUDED_

typedef struct Foo Foo;

struct Foo {
    int number;
} MYFOO = {2};

void helloWorld (void);

#include "Bar.c"
#define _BAR_C_INCLUDED_

#endif

现在Bar.c

void helloWorld() {
    printf("Hello world\n");
}

最后,Foo.c-在此处包括stdio.h以及Bar.h(对于我们而言,这反过来又包括Bar.c):

#include <stdio.h>

#include "bar.h"

int main() {
    helloWorld();
}

并进行编译:

gcc Foo.c -o Foo -Wall

答案 1 :(得分:1)

反复研究之后,我发现错误的原因来自MYFOO = {2};

这与我在头文件中初始化结构有关。 头文件用于定义而不是初始化。 相反,解决该问题的方法是简单地在相应的源文件Foo.c中定义和初始化行。

现在,在该文件中,我将其作为全局变量包括在内:

Foo MYFOO = {2};

现在可以在任何其他文件(例如,在我的Bar.c中)访问此变量,我所要做的就是添加一行,

extern Foo MYFOO;

这解决了我的编译问题,这意味着我可以根据需要在其他文件中使用该结构!