是这样的,在学习郑莉老师的多文件结构和编译预处理命令章节时候,看到书里有这么一张图描述如下:#include指令作用是将指定的文件嵌入到当前源文件中#include指令所在的位置。

然后我就想5_10.cpp主程序直接include了point.cpp也可以吧(因为point.cpp里include了point.h,这样既有声明又有定义)。没错,书中继续描述被嵌入的文件可以是.h文件,也同样可以是.cpp文件。但是当我在eclipse for c++环境里验证的时候却打脸了,让我一度怀疑是不是不能#include .cpp。

eclipse中在连接的那一步报错了,如下:

并没有认真看eclipse中报错内容的我在vim中一顿操作验证结果明明可以引入cpp的啊。上半部分是include .h的测试,下半部分是include .cpp的测试,都可以看出在生成.o文件也就是编译生成目标代码并没啥错,就在连接步骤引入.h的却报错,引入.cpp却正常(这结果与在eclipse中刚好相反啊),这不禁让我思考了起来,哦发现了,在命令行中我是用命令指定编译哪个cpp文件,在引入.h的test.cpp测试中我只编译了test而没有编译也没连接point.cpp,所以连接时候找不到函数地址就很正常了(可以注意到它报的错是undefined,而eclipse中报的是duplicate,这就是区别...)

回到eclipse,往上翻错误,看到eclipse好像是把我项目底下所有cpp都给编译了,一看果然是...emmm make all。其实编译就编译吧也没有啥影响最后别连接那些我没用的就行,但是可以看到这个真的是linker 了all啊..


由于我在main.cpp中include了6文件夹的Point.cpp,这就相当于把6文件夹下的Point.cpp编译了两次(产生了两个关于point.cpp的符号表,关于什么是符号表,就是把程序中各个标识符名称和它们在各段中的地址关联起来的数据结构,见下图)。然后在连接的时候,是将各个编译单元的目标文件和运行库当中被调用过的单元加以合并,经过合并后不同编译单元代码段和数据段就分别合并到一起,与此同时,各个目标文件的符号表也可以被综合起来,连接最后符号表的每个条目都必须有确定的地址。然而eclipse连接报错就报错在符号表的函数地址应该是什么,main中所引用的Point.cpp和6文件夹的Point.cpp是一个东西,但却在生成.o文件时候符号表中的Point类的各个函数各自有了地址。


符号表能够被正确综合的一个前提是,对于同一个符号,只在刚好一个编译单元中有定义,而在其他编译单元中是未定义的。之所以有这个要求是因为合并后符号表中各个符号的地址需要根据该符号在有定义的编译单元中的相对地址来确定。若在多个编译单元中同一个符号都有定义地址,那么它的地址将无所适从,就会出现符号定义冲突的连接错误。所以可以看到eclipse给出的错误提示是"duplicate symbol".

其中形如__ZN5...的名字是函数名,在符号表中函数并不只以它在源程序中的名字命名,函数在符号表中的名字至少包括源程序的函数名和参数表类型信息。因为函数可以重载,由于符号表中没有专门的类型信息,参数表信息只能在名字中有所体现,否则在目标文件中无法对函数名相同单参数不同的函数加以区分。look,其中move函数就是我point类中定义的一个成员函数,剩下的都是构造函数(我定义的+类中默认的其他构造)或析构函数把。所以,看来在eclipse中要非想引用cpp文件就要自己重写eclipse中的make文件咯。

C++编译连接过程中关于符号表的报错分析的更多相关文章

  1. 蘑菇街TeamTalk编译连接过程中遇到的问题及解决方法(iOS)

    今天浏览博文的时候,“蘑菇街开源的即时通讯框架,包括iOS.Android.Mac.Windows客户端和后台 Github源码下载地址:https://github.com/mogujie/Team ...

  2. Coding编译连接过程中遇到的问题及解决方法(iOS)

    Coding 上下载地址:https://coding.net/u/coding/p/Coding-iOS/git Github源码下载地址:https://github.com/Coding/Cod ...

  3. kerkee demo编译连接过程中遇到的问题及解决方法(iOS)

    https://github.com/kercer/kerkee_ios 1.刚打开这个demo的时候是下图这个样子的,我们很自然的可以想到将kerkee.xcoderproj添加到项目里面 2.将k ...

  4. 【Azure 存储服务】Hadoop集群中使用ADLS(Azure Data Lake Storage)过程中遇见执行PUT操作报错

    问题描述 在Hadoop集中中,使用ADLS 作为数据源,在执行PUT操作(上传文件到ADLS中),遇见 400错误[put: Operation failed: "An HTTP head ...

  5. pythonmysql运行报错解决过程中遇到的其中一个报错解决文章来源

    本文章仅记录下面报错的解决文章来源:error: command 'C:\Users\Administrator\AppData\Local\Programs\Common\Micr osoft\Vi ...

  6. 安装Lync 2013过程中遇到的第一个报错

    安装Lync 2013, 首先要去做的就是prepare AD Forest. 在使用向导的时候会遇到报错如下: Prepare Forest Active Directory setting exe ...

  7. 解决vue项目运行过程中,npm run dev 报错问题

    [方案1] 错误如下: npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! travel@1.0.0 dev: `webpack-dev-server ...

  8. Storm编译打包过程中遇到的一些问题及解决方法

    作者: 大圆那些事 | 文章可以转载,请以超链接形式标明文章原始出处和作者信息 网址: http://www.cnblogs.com/panfeng412/archive/2013/11/30/som ...

  9. MySQL中遇到的几种报错及其解决方法

    MySQL中遇到的几种报错及其解决方法 1.[Err] 1064 - You have an error in your SQL syntax; check the manual that corre ...

随机推荐

  1. hdu-1082 Matrix Chain Multiplication---栈的运用

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1082 题目大意: 题意大致是N个矩阵,如果要求计算的矩阵例如(AB),如果A的列等于B的行,进行:A ...

  2. Menubutton按钮弹出菜单

    #按钮弹出菜单 from tkinter import * root =Tk() def callback(): print('我被调用了') m = Menubutton(root,text = ' ...

  3. SpringCloud异常(Euruka):Application run failed java.lang.NoSuchMethodError: org.springframework.boot.builder.SpringApplicationBuilder

    在测试Euruka作为服务注册中心的时候碰到了这个问题,错误提示如下: "C:\Program Files\Java\jdk1.8.0_161\bin\java" -XX:Tier ...

  4. js判断网络连通性

    js判断网络连通性 if (window.navigator.onLine == true) {                         console.log("首次 -- 已连接 ...

  5. MyBatis 与 Spring 整合

    MyBatis-Spring 项目 目前大部分的 Java 互联网项目,都是用 Spring MVC + Spring + MyBatis 搭建平台的. 使用 Spring IoC 可以有效的管理各类 ...

  6. 安卓开发JAVA基础之初识JAVA

    JAVA的一大特点------不依赖平台 JAVA在平台之上提供了一个JAVA运行环境(Java  Runtime Environment, JRE),该环境由Java虚拟机(Java  Virtua ...

  7. [HDU 3507]Print Article

    Description Zero has an old printer that doesn't work well sometimes. As it is antique, he still lik ...

  8. [IOI2007]训练路径

    Description 马克(Mirko)和斯拉夫克(Slavko)正在为克罗地亚举办的每年一次的双人骑车马拉松赛而紧张训练.他们需要选择一条训练路径. 他们国家有N个城市和M条道路.每条道路连接两个 ...

  9. ●BZOJ 4698 Sdoi2008 Sandy的卡片

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4698 题解: 后缀数组,二分这个题还是比较套路的.首先依据题意,把各个串差分以后,用分割符号 ...

  10. Linux添加系统调用的两种方法

    前言 系统调用的基本原理 系统调用其实就是函数调用,只不过调用的是内核态的函数,但是我们知道,用户态是不能随意调用内核态的函数的,所以采用软中断的方式从用户态陷入到内核态.在内核中通过软中断0X80, ...