需要 "multiple definition" 错误的解决方法
need a workaround for a "multiple definition" error
说明我的问题的玩具代码如下:
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
但遇到了同样的问题。
当您将变量定义放入头文件时,任何包含它的 .c 文件都将具有该变量的副本。然后,当您尝试 link 它们时,会出现多重定义错误。
您的头文件应仅包含变量的 声明。这是使用 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");
}
不清楚为什么要使用这么多全局变量。数组
int testarr[]={1,2,3};
被定义的次数与包含相应 header.
的编译单元(在您的示例中至少有两个编译单元)一样多
在header中声明数组,如
extern int testarr[3];
并在 cpp 模块中定义它。
int testarr[]={1,2,3};
其他具有外部链接的全局变量也是如此。
至此备注
BTW, based on something else I found, I tried defining testarr as
extern but got the same problem.
则不应在header 中初始化带有说明符extern 的数组。否则就是数组的定义。
说明我的问题的玩具代码如下:
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
但遇到了同样的问题。
当您将变量定义放入头文件时,任何包含它的 .c 文件都将具有该变量的副本。然后,当您尝试 link 它们时,会出现多重定义错误。
您的头文件应仅包含变量的 声明。这是使用 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");
}
不清楚为什么要使用这么多全局变量。数组
int testarr[]={1,2,3};
被定义的次数与包含相应 header.
的编译单元(在您的示例中至少有两个编译单元)一样多在header中声明数组,如
extern int testarr[3];
并在 cpp 模块中定义它。
int testarr[]={1,2,3};
其他具有外部链接的全局变量也是如此。
至此备注
BTW, based on something else I found, I tried defining testarr as extern but got the same problem.
则不应在header 中初始化带有说明符extern 的数组。否则就是数组的定义。