说明我的问题的玩具代码如下:
stuff.h:
#ifndef STUFF
#define STUFF
int a;
int testarr[]={1,2,3};
#endif
fcn.h:
#include "stuff.h"
int b[]={5,6,7};
void fcn();
main.h:
#include "stuff.h"
#include <stdio.h>
fcn.c:
#include "main.h"
void fcn() {
printf("Hello\n");
}
main.c中:
#include "main.h"
#include "fcn.h"
int main() {
fcn();
printf("HI\n");
}
尝试编译失败:
/g/pe_19976/fcn_2.o:(.data+0x40): multiple definition of `testarr'
/g/pe_19976/main_1.o:(.data+0x40): first defined here
在做了一些阅读之后,我意识到在头文件中定义数组testarr
是个问题。但问题是,在我的实际代码中,有几个文件需要访问testarr
,并且它需要在任何地方都具有相同的指定值。我想我可以把它放在main.h
(?)中,但即使这样可行,在我的真实代码中它在逻辑上属于stuff.h
。我该如何解决这个难题?
顺便说一句,基于我发现的其他内容,我尝试将testarr
定义为extern
,但遇到了同样的问题。
答案 0 :(得分:3)
将变量定义放入头文件时,包含它的任何.c文件都将具有该变量的副本。然后,当您尝试链接它们时,会出现多重定义错误。
您的标头文件应仅包含变量的声明。这是使用extern
关键字完成的,没有初始化程序。
然后在一个.c文件中,将定义与可选的初始化程序一起放入。
例如:
main.c中:
#include "main.h"
#include "fcn.h"
int a;
int testarr[]={1,2,3};
int main() {
fcn();
printf("HI\n");
}
stuff.h:
#ifndef STUFF
#define STUFF
extern int a;
extern int testarr[];
#endif
fcn.h:
#include "stuff.h"
extern int b[];
void fcn();
fcn.c:
#include "main.h"
int b[]={5,6,7};
void fcn() {
printf("Hello\n");
}
答案 1 :(得分:0)
目前尚不清楚为什么要使用这么多全局变量。数组
ln
定义为多次,因为编译单元(在您的示例中至少有两个编译单元)包含相应的标题。
在像
这样的标题中声明数组int testarr[]={1,2,3};
并在cpp模块中定义它。
extern int testarr[3];
同样适用于具有外部链接的其他全局变量。
至于这句话
顺便说一句,基于我发现的其他东西,我尝试将testarr定义为 extern但是遇到了同样的问题。
然后,不应在标题中初始化具有说明符extern的数组。否则它是数组的定义。