multiple definition of XXX情况分析
近日在写代码,各个.cpp源文件编译时没有问题,将*.o进行链接时,出现了许多multiple definition of XXX的链接错误。于是在网上搜索了一番,结合自己的代码包含逻辑,最终发现了问题,记载如下:
一、问题描述:
Threadpool.h:
声明了一些函数原型和一些全局变量,这些标示符是没有带extern关键字的。
Threadpool.cpp:
该cpp文件对Threadpool.h中函数进行定义,变量给出初始值。
单独编译g++ -g -c Threadpool.cpp不会有问题。
Main.cpp:
我在Main.cpp中需要用到Threadpool.cpp中定义好的函数以及变量,所以我在Main.cpp中#include "Threadpool.h"。
单独编译g++ -g -c Main.cpp 也没有问题。
当进行链接时:g++ -o Main Threadpool.o Main.o -lpthread
就会出现:multiple definition of XXX
二、题产生的原因:
C/C++中一个.c和.cpp文件以及其include到的头文件称为一个编译单元,该单元是独立编译的。一个标示符可以多次声明,但是只能够定义一次。
为什么Threadpool.cpp和Main.cpp都包含Threadpool.h,在链接阶段会出现重复定义的符号呢?真正的问题出在头文件标示符。
Threadpool.h:
int a;
double d;
int fnu();
//etc
在Threadpool.cpp中#include时被预处理器处理之后,出现了一次定义。
int a;
double d;
int fnu();
在Main.cpp中#include同样被预处理器处理之后:再一次出现了定义。
int a;
double d;
int fnu();
为什么编译阶段不会出现问题呢?
执行g++ -g -c Threadpool.cpp时,对应的.cpp文件将会被编译成目标文件,目标文件含有一系列Threadpool.h中定义过的标示符。
执行g++ -g -c Main.cpp时,对应的.cpp文件也将会被编译成目标文件,目标文件同样含有一系列Threadpool.h中定义过的标示符。
上述二者被独立的编译成目标文件,所以编译不会有问题。
我们可以这样想象-c每一个源文件时,相当于一条有管道包围的纵向水流,二者互不干扰。当-o链接时两条原本相互独立的水管横向流了,所有就出现了重复的元素。所以当进行链接时:g++ -o Main Threadpool.o Main.o -lpthread。就会出现重复定义的标示符。重复定义的标示符在这里只是变量,函数不会。因为函数确实只在.cpp中定义了一次,多次声明是没有问题的,而变量确实出现了两次定义。
三、我的解决方案:
不在头文件中定义全局变量,头文件中只含有函数的原型声明,而将所有的全局变量放入Threadpool.cpp中,当Main.cpp需要用到这些全局变量时,extern一下,告诉编译器这些变量是在其他源文件中定义的。
得到的启示:
(1)最好不要在头文件中定义全局变量。
(2)在C/C++中分清楚标示符的声明(declared)和定义(definition)的区
别很重要。
(3)该问题与没有用#ifndef,#define,#endif产生问题的原因是不一样的。
非常好的一篇blog,我在写代码的时候也碰到了类似的问题,其实也是全局变量和函数的重复定义的问题!!!但是我的例子比较复杂,不好描述,而作者的例子清晰易理解,故转载过来。另外这篇文章最令我受益的一句话是:
C/C++中一个.c和.cpp文件以及其include到的头文件称为一个编译单元,该单元是独立编译的。一个标示符可以多次声明,但是只能够定义一次。
文章转载自:http://blog.csdn.net/luo6620378xu/article/details/8511312
multiple definition of XXX情况分析的更多相关文章
- 链接错误:multiple definition of 'xxx' 问题解决及其原理
内容借鉴 于CSDN炸鸡叔 错因 截图: “multiple definition of 'head' ” “multiple definition of 'tail' ” 解决过程: 1.首先要 ...
- Arm开发板+Qt学习之路-multiple definition of
问题描述:在一个头文件a.h中定义一些变量x,在其他.c文件中(b.c,c.c)要用到.用一般的全局变量的方法,编译时总是提示error:multiple definition of x 问题分析:o ...
- multiple definition of `err_sys' 《UNIX环境高级编程》
本文地址:http://www.cnblogs.com/yhLinux/p/4079930.html 问题描述: [点击此处直接看解决方案] 在练习<UNIX环境高级编程>APUE程序清单 ...
- gcc: multiple definition of [转]
/home/tace/openav/source/SeamlessMessage/CPaoFlt.o: In function `CPaoFlt::get_m_strPrmair() const':C ...
- multiple definition of 问题解决方法
在最近的项目里,由于我想重载结构体的==操作符,然而大意的我把重载的过程写在了头文件里,所以导致了multiple definition of的错误.现在总结下解决方法: 首先,最关键的,不要把全局变 ...
- 复旦大学2015--2016学年第二学期高等代数II期末考试情况分析
一.期末考试成绩班级前几名 胡晓波(90).杨彦婷(88).宋卓卿(85).唐指朝(84).陈建兵(83).宋沛颖(82).王昊越(81).白睿(80).韩沅伯(80).王艺楷(80).张漠林(80) ...
- 复旦大学2015--2016学年第一学期高等代数I期末考试情况分析
一.期末考试成绩班级前几名 胡晓波(93).宋沛颖(92).张舒帆(91).姚人天(90).曾奕博(90).杨彦婷(90).白睿(88).唐指朝(87).谢灵尧(87).蔡雪(87) 二.总成绩计算方 ...
- 复旦大学2014--2015学年第二学期高等代数II期末考试情况分析
一.期末考试成绩班级前几名 钱列(100).王华(92).李笑尘(92).金羽佳(91).李卓凡(91).包振航(91).董麒麟(90).张钧瑞(90).陆毕晨(90).刘杰(90).黄成晗(90). ...
- 8月17日 Power-BI关于全国房地产开发投资情况分析 QQ群视频交流开课啦
<ignore_js_op> 数读|中国的经济只剩下房地产了么? 引言: 近日一则标题为“房奴们又立功啦,7月份新增贷款几乎都来自房贷!”的报道吸引了大众的目光.该报道指出在央行8月13日 ...
随机推荐
- import Vue form 'vue’的意思
1.import Vue form ‘vue’ 写全的话是import Vue from ‘…/nodemouls/vue/list/vue.js’: 此时在webpack.base.conf.js中 ...
- 前端 HTML form表单标签 textarea标签 多行文本
<textarea></textarea>作用:允许用户录入多行数据到表单控件中 <!DOCTYPE html> <html lang="en&qu ...
- 虚存管理页面置换算法 — FIFO和RUL算法模拟实现
本篇博文为追忆以前写过的算法系列第一篇(20081021) 温故知新 目的: 为了解决内存容量有限与多作业执行的冲突.运用了虚拟存储技术.能从逻辑上对内存进行扩充,达到扩充内存的效果.分页存储管理是实 ...
- 002-读书笔记-企业IT架构转型之道-阿里巴巴中台战略思想与架构实战-第二章 构建业务中台的基础-共享服务体系简介
2.1.回归SOA的本质-服务重用 SOA理念的核心价值:松耦合的服务带来业务的复用,通过服务的编排助力业务的快速响应和创新. 现有模式多是烟囱式结合 ESB 企业总线打通不同系统间的交互. 2.2. ...
- 万恶之源 - Python模块二
shelve 我们之前学了json和pickle模块 这些都是序列化的模块,咱们进行在讲一个序列化的东西 叫做shelve 你们肯定有个疑问,这个东西和那个类似为什么要讲.是因为这个模块比较简单的,并 ...
- centos上shellcheck的安装
关于shellcheck的作用和功能,自行查阅. centos7 上安装shellcheck的过程中查了很多资料,大部分都是在ubunt下安装的,centos的比较少,然后好不容易看到一个https: ...
- python regularexpress1
//test.py 1 import re 2 3 print (re.search('www', 'www.myweb.com').span()) 4 print (re.search('com', ...
- 原生js---ajax---get方法传数据
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- VS.C#如何向数据数据库中存入和读取图片的
写入图片部分代码:假设图片为 test.gifbyte [] bytes = File.ReadAllBytes(@"c:\test.gif");SqlConnection con ...
- html常用文本标签(转)
内容一<br />内容二 让文本强制换行 内容一内容二 <p>段落一</p><p>段落二</p> 段落标签 段落一 段落二 <b> ...