转载请注明出处
Windows下C++编程,通过VC生成工程,编写C++源文件,点运行,代码没问题直接出结果。VC什么都帮我们搞了,不了解其中过程也完全没问题。
转到linux下写c++,总觉得有点虚,毕竟很多时候需要自己去构建。网上找了一些相关的文章,大多讲得高深,弄懂其过程后来写一篇不高深但易懂的,方便回忆。有不准确的地方欢迎指正。
 
C++包括源文件(.cpp)和头文件(.h),头文件包含变量的声明和类定义,源文件包含变量的定义。当然你也可以只用源文件来组织程序,但使用.h文件可以使程序结构更清晰。
linux下,c++生成二进制文件通常使用1条命令即可
  g++ source1.cpp source2.cpp source3.cpp -o main
其实这过程包含预处理、编译和链接3个过程,预处理包含宏定义、包含指令和条件编译指令。
 
宏定义是简单的替换,将某个变量值替换为另一个内容,之前学C的时候把它当全局变量使用(#define PI 3.14),包含指令可以包含其他C++文件,一般包含.h文件,预处理后可以将包含的.h文件内容展开(.h文件中包含的文件也被展开)。条件编译利用宏定义和包含指令,对代码展开内容做控制。比如:main.cpp中include "student.h"、include "teacher.h",student.h文件中又include "teacher.h",那么teacher.h被include了2次,Teacher类重复定义,编译会报错。在Teacher.h中可以使用条件编译(#ifndef _TEACHER_H #define _TEACHER_H ... #endif),保证Teacher定义只有一次。
 
编译过程将每个编译单元的代码翻译为机器码,每个编译单元产生一个目标文件(包含未解决符号表、导出符号表、地址重定向表和机器码)。变量、函数分为外链接(extern,符号导出)和内链接(static,符号不导出)
static和extern
  static:在example.h文件中全局范围内定义的变量x,变量a只可以在本编译单元内使用,不对外暴露该变量(链接时不会令其他编译单元拿到该变量)。所以,a.cpp文件(a编译单元)只要include "example.h",就可以在本编译单元使用变量x。b.cpp(b编译单元)也include "example.h",也可以在它的编译单元内使用变量x。使用的是各自版本的x,链接时彼此不冲突。
  extern:全局变量的声明,变量可以声明多次,不会报错。extern int x,本编译单元会操作一个变量x,但x的定义并不在此编译单元。所以编译时发现访问没有定义的变量x不会报错,在链接时会找到它的定义,多个编译单元共享一个全局变量。
所以,在.h文件中全局变量的定义,要么是static的,各编译单元用各自的。要么是extern的声明,我要用到一个全局变量,如果没找到定义就在别的编译单元内找找。如果在.h文件中定义一个变量,不合理。.h文件可能会被多个编译单元include,那链接时必然出现变量重定义。
      
链接过程将多个目标文件链接(依赖目标文件的3个表),组成完整二进制程序。此时可能的错误有:extern的变量却没有找到定义在哪;某个变量被多次定义。
 
以上就是C++源文件到可执行程序的处理过程,细节比这描述要复杂得多,但还是要先有骨再有肉。欢迎一起讨论。

C++生成二级制文件过程(预处理->编译->链接 )的更多相关文章

  1. C语言预处理编译链接各个阶段错误,分阶段的说一下

    C语言预处理编译链接各个阶段错误,分阶段的说一下 C语言预处理编译链接各个阶段错误,分阶段的说一下比如指针异常,数组下标越界什么的    我来答 1个回答 #热议# 你觉得这辈子有希望看到996消失 ...

  2. gitbook生成的_book文件本地打开后链接失效问题

    Gitbook 生成本地 html 的问题 在本地用 gitbook-cli根据 Summary 生成目录 然后在每个 md 文件里书写内容 然后用 gitbook serve .生成本地 html ...

  3. 【C编程基础】C编译链接命令gccc

    1.gcc安装 rpm -qa|grep gcc ==>检查gcc是否安装 gcc -v ==>检查gcc版本 yum -y install gcc ==>安装gcc  2.基本语法 ...

  4. 1.预处理,生成预编译文件(.文件): Gcc –E hello.c –o hello.i 2.编译,生成汇编代码(.s文件): Gcc –S hello.i –o hello.s 3.汇编,生成目标文件(.o文件): Gcc –c hello.s –o hello.o 4.链接,生成可执行文件: linux笔记

    1 动态查看日志 tail -f filename tail -1000f filename 2 解压当前目录内容为xxx.zip  zip -r xxx.zip ./* 3 查看内存使用情况 fre ...

  5. GCC编译器原理(三)------编译原理三:编译过程---预处理

    Gcc的编译流程分为了四个步骤: 预处理,生成预编译文件(.文件):gcc –E hello.c –o hello.i 编译,生成汇编代码(.s文件):gcc –S hello.i –o hello. ...

  6. 由动态库文件dll生成lib库文件(手动生成.def文件,然后使用lib命令编译,非常牛),同理可使用dll生成.a库文件

    本文基于OpenBlas的编译和安装,来说明如何从一个dll文件生成lib库文件. 参考OpenBlas的说明“Howto generate import library for MingW”,和Mi ...

  7. python3 pyinstaller生成exe文件过程问题解决记录

    1.使用pip安装pyinstaller 2.在cmd打开需生成可执行文件的python文件所在文件夹 3.使用命令pyinstaller -F -w **.py (代码中有import其他模块的,只 ...

  8. ROS知识(16)----如何编译时自动链接同一个工作空间的其他包的头文件(包含message,srv,action自动生成的头文件)

    catkin_make编译时,往往需要自动链接同一个工作空间的其他包的头文件.否则会出现类似如下的错误: /home/xx/xx_ws/srcA_package/src/db.hpp:13:26: f ...

  9. boost库生成文件命名和编译

    生成文件命名规则:boost中有许多库,有的库需要编译.而有的库不需要编译,只需包含头文件就可以使用.编译生成的文件名字普遍较长,同一个库根据编译链接选项不同,又可以生成多个不同名字的文件.生成的文件 ...

随机推荐

  1. flex进行页面的基础布局

    接触flex有一段时间了,由于自己在移动上的经验比较少,一直以为这个和css3的其他属性差不多,就是一个盒模型的缩放之类的.今天一个移动的小项目用到了这个属性,仔细看了下,先不说里面具体的属性,就fl ...

  2. 汇总常用的jQuery操作Table tr td方法

    虽然现在DIV+CSS进行页的布局大行其道,但是很多地方使用table还是有很多优势,用table展示数据是比较方便的,下面汇总了jQuery操作Table tr td常用的方法,熟记这些操作技巧,下 ...

  3. css样式重置,不建议用通配符

    由于各个浏览器对css样式的默认样式不一致,所以有必要进行样式重置.在网上看到很多建议使用 *{margin:0;padding:0} 重置margin和padding.建议不这样子使用,原因主要是性 ...

  4. 给自己的Unity添加声音文件

    下面说明一下,在Unity 里是怎么样加载声音文件的. Unity同时支持单声道和立体声音频资产. Unity支持导入以下音频文件格式:.aif, .wav, .mp3, 和 .ogg,和以下音轨模块 ...

  5. android开发中监控android软件网络请求的软件Charles使用入门

    1.下载并安状软件,官网在此: http://www.charlesproxy.com/ 2.前题条件,电脑和手机必须在同一网段 3.在Charles界面选择菜单 proxy->proxy se ...

  6. 重启Ubuntu后Hadoop的namenode起不来的解决办法‬

    因为Ubuntu每次重启之后都会将/tmp目录清空,而默认配置下每次hadoop name node -format总是将数据信息定位到/tmp/hadoop-${user.name}中,因此需要修改 ...

  7. 【leetcode】Unique Paths

    A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...

  8. Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...

  9. HTML5学习生涯1--touchmove中遇到的问题

    在使用html5做在手机上显示轮播图片的效果时突然遇到touchmove事件在touchstart事件之后只触发了一次touchmove之后和touchend一起触发了一次,咦,这是怎么回事?怎么不和 ...

  10. NetMq学习--发布订阅(一)

    基于NeqMq 4.0.0-rc5版本发布端: using (var publisher = new PublisherSocket()) { publisher.Bind("tcp://* ...