g++ 链接 变量被多次定义?

发布于 2022-09-06 04:19:05 字数 1120 浏览 34 评论 0

这是map_test.h文件

#ifndef _MAP_TEST_H
#define _MAP_TEST_H

#include <map>
#include <string>

using std::map;
using std::string;

map<string, string> map_config;

void init_map_config();

#endif

这是map_test.cpp文件

#include "map_test.h"

void init_map_config()
{
    map_config.insert({"123", "123"});
    map_config.insert({"456", "456"});
    map_config.insert({"789", "789"});
}

这是main.cpp文件

#include <iostream>
#include "map_test.h"

using std::cout;
using std::endl;

int main()
{
    init_map_config();

    for (auto it = map_config.begin(); it != map_config.end(); it++)
        cout << it->first << " " << it->second << endl;
    cout << endl;
}

编译:
g++ -c map_test.cpp -o map.o -std=c++11
g++ -c main.cpp -o main.o -std=c++11
编译都是成功的,链接过程出错:
g++ map.o main.o -o main
此时出错:

main_test.o:(.bss+0x0): `map_config'被多次定义
map_test.o:(.bss+0x0):第一次在此定义
collect2: error: ld returned 1 exit status

为什么会报错?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风向决定发型 2022-09-13 04:19:05

因为违背了ODR。map_config定义在头文件中,并且是外部链接。这个头文件分别被两个源文件包含,这导致链接时map_config在两个目标文件中有定义。

解决方案是将定义移到源文件中,在头文件中只留下纯声明。

神魇的王 2022-09-13 04:19:05

1,在map_test.cpp文件中定义map<string, string> map_config;
2,在map_test.h中使用extern map<string, string> map_config;

像你 2022-09-13 04:19:05

变量和函数的定义 , 都应该放在cpp文件中, 否则很容易产生多重定义.
为什么呢?
因为c++的编译单位是cpp文件. 如果这个头文件被多个cpp包含了, 那么这个头文件中的定义的变量或者 函数就会在这些cpp生成的obj中存在, 在链接的时候, 就会发现多个obj存在同一个变量或者函数实现, 自然就会报重定义了.

所以:
除非你能清楚的知道, 这个头文件只会被一个cpp文件包含一次. 那么放到头文件中没有问题.
如果不确定, 那么变量定义或者函数的实现, 就老实的放到.cpp文件中吧.

可能你要问, 变量放到.cpp中的, 那么其它文件中如何使用它呢?
答案是使用声明: extern
比如: extern map<string, string> map_config;

我也只是我 2022-09-13 04:19:05

有两种解决办法

  1. 在头文件中使用extern声明,在源文件中定义

  2. 将map<string, string> map_config和函数init_map_config都定义为static

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文