提问人:mazix 提问时间:7/21/2013 最后编辑:mazix 更新时间:2/7/2022 访问量:184300
多重定义...链接器错误
Multiple definition of ... linker error
问:
我定义了一个特殊的文件:config.h
我的项目也有文件:
t.c, t.h
pp.c, pp.h
b.c b.h
l.cpp
以及 #includes:
在T.C.中:
#include "t.h"
#include "b.h"
#include "pp.h"
#include "config.h"
在不列颠哥伦比亚省:
#include "b.h"
#include "pp.h"
在pp.c中:
#include "pp.h"
#include "config.h"
在 l.cpp 中:
#include "pp.h"
#include "t.h"
#include "config.h"
“我的文件”中没有 include 指令,只有“文件”中的包含指令。我在config.h中定义了这一点:*.h
*.c
const char *names[i] =
{
"brian", "stefan", "steve"
};
并且需要 l.cpp、t.c、pp.c 中的数组,但我收到此错误:
pp.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
t.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [link] Error 1
我在项目中使用的每个文件中都包含防护装置。有什么帮助解决这个问题吗?*.h
答:
163赞
Yu Hao
7/21/2013
#1
不要在标头中定义变量。将声明放在标头中,将定义放在其中一个 .c 文件中。
在 config.h 中
extern const char *names[];
在某些 .c 文件中:
const char *names[] = {
"brian", "stefan", "steve" };
如果将全局变量的定义放在头文件中,则此定义将转到包含此标头的每个 .c 文件,并且您将收到多个定义错误,因为可变变量可以多次声明,但只能定义一次。
此外,如果必须在头文件中定义变量,则可以使用关键字,还可以做另一件事。static
static const char *names[] = {
"brian", "stefan", "steve" };
这样,变量将在整个程序中只定义一次,并且可以多次访问。names
评论
1赞
mazix
7/21/2013
解决!:)你能告诉我为什么我不应该把声明放在文件中吗?h*.
7赞
Jiminion
7/21/2013
所以它不会这样做。仅使用 *.h 文件来引用信息。您必须记住,“include”意味着它包含该文件中的所有 *.h 信息,因此您将使用 *.h 将该信息(而不仅仅是引用)复制到每个文件中。这可能会让链接者感到困惑,而且确实如此。
4赞
Yu Hao
7/21/2013
@mazix 否,全局变量的定义应该转到 .c 文件,并将声明放在标头中。请记住,您可以多次声明可变变量,但只能定义一次。
1赞
Spalteer
7/21/2013
只是为了使解释稍微清楚一点,头文件可能包含在多个 c 文件中,因此您最终会得到具有相同名称的变量的多个声明
0赞
Ebrahim Karimi
10/28/2018
是否可以用于类构造函数?extern
52赞
JonathanWhittenberg
8/16/2014
#2
公共函数的声明在头文件中,是的,但定义在头文件中也是绝对有效的!如果在实用程序函数的标头中定义不希望在每个 c 文件中再次定义的内容,则可以将定义声明为静态(整个程序只允许 1 个副本)。即定义一个枚举和一个静态函数来将枚举转换为字符串。然后,您不必为每个包含标头的 .c 文件将枚举重写为字符串转换器。:)
评论
4赞
Saik
5/28/2017
实际上,我发现这个答案比顶部答案方便得多。例如,只有一个标头来存储所有全局变量,而不是 .h 和 .cpp 文件,这更方便和有吸引力。谢谢。
0赞
Alejandro Galera
5/3/2018
我认为这个解决方案也比投票最多的解决方案更好,因为另一个需要在每个 *.c 文件中定义值,而且您的@JonathanWhittenberg看起来更优雅。多谢
1赞
SimonC
1/9/2019
比 AA 更好、更优雅的解决方案。+1 添加为什么这并不总是一个坏主意。
9赞
PPenguin
6/8/2019
这并不是对静态作用的准确描述。“您可以将定义声明为静态(整个程序只允许 1 个副本)”不!static 使定义范围限定为该编译单元。因此,它为每个编译单元提供一个副本。因此,如果你有一些大的字符串列表,你的程序最终将有许多重复的副本。每个 C 文件一个。如果稍后进行调试,则对于静态函数来说,情况会更糟,因为不再有单个函数可以放置断点,而是在生成的链接程序中该函数的许多副本。
0赞
Phrunsys Emmason
2/7/2022
#3
使定义在头文件中保持静态。
评论