我正在尝试在头文件中创建结构,并初始化模板结构。出于某种原因,当将头文件包含在多个文件中时,它给了我以下错误:
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 有关,而最终两次包含了该结构?但是我该如何避免这样的事情?
谢谢!
答案 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;
这解决了我的编译问题,这意味着我可以根据需要在其他文件中使用该结构!