出于某种原因,我在头文件中获得了多个内容声明,即使我正在使用标题保护。我的示例代码如下:
main.c中:
#include "thing.h"
int main(){
printf("%d", increment());
return 0;
}
thing.c:
#include "thing.h"
int increment(){
return something++;
}
thing.h:
#ifndef THING_H_
#define THING_H_
#include <stdio.h>
int something = 0;
int increment();
#endif
当我尝试编译它时,GCC说我对some变量有多个定义。 ifndef应该确保不会发生这种情况,所以我很困惑为什么会这样。
答案 0 :(得分:10)
包含警卫功能正常,不是问题的根源。
包含thing.h
的每个编译单元都会获得自己的int something = 0
,因此链接器会抱怨多个定义。
以下是解决此问题的方法:
thing.c:
#include "thing.h"
int something = 0;
int increment(){
return something++;
}
thing.h:
#ifndef THING_H_
#define THING_H_
#include <stdio.h>
extern int something;
int increment();
#endif
这样,只有thing.c
的实例会something
,而main.c
会引用它。
答案 1 :(得分:4)
标题保护将阻止文件在同一编译单元(文件)中多次编译。你将它包含在main.c和thing.c中,因此它将在每个单元中编译一次,导致变量something
在每个单元中声明一次,或者总共两次。
答案 2 :(得分:3)
每个翻译单元都有一个定义(main.c
中有一个,thing.c
中有一个)。标题保护会阻止标题在单个翻译单元中被多次包含。
您需要在头文件中声明 something
,并且只在<{1}}中定义,就像函数一样:
thing.c:
thing.c
thing.h:
#include "thing.h"
int something = 0;
int increment(void)
{
return something++;
}
答案 3 :(得分:1)
变量something
应该在.c
文件中定义,而不是
在头文件中。
仅变量和函数原型的结构,宏和类型声明
应该在头文件中。在您的示例中,您可以在头文件中将something
的类型声明为extern int something
。但是变量本身的定义应该在.c
文件中。
通过您所做的工作,将定义变量something
在包含.c
的每个 thing.h
文件中,您获得了一个
GCC尝试链接时出现“多次定义的内容”错误消息
一切都在一起。
答案 4 :(得分:1)
尽量避免全局定义变量。 使用increment()等函数来修改和读取其值。 这样你可以将变量静态保存在thing.c文件中,并且你确定只有该文件中的函数才会修改该值。
答案 5 :(得分:0)
ifndef
所守护的是.h
中不止一次包含.c
的{{1}}。例如
的事情。 ħ
#ifndef
#define
int something = 0;
#endif
thing2.h
#include "thing.h"
main.c
#include "thing.h"
#include "thing2.h"
int main()
{
printf("%d", something);
return 0;
}
如果我离开ifndef
,那么 GCC 会抱怨
In file included from thing2.h:1:0,
from main.c:2:
thing.h:3:5: error: redefinition of ‘something’
thing.h:3:5: note: previous definition of ‘something’ was here