转载请注明出处
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. (转)EntityFramework之领域驱动设计实践

    EntityFramework之领域驱动设计实践 - 前言 EntityFramework之领域驱动设计实践 (一):从DataTable到EntityObject EntityFramework之领 ...

  2. new的原罪

    一直以为在开发阶段能够直接调用的,速度而言一定是最优秀的,因为总比后期通过反射之类来调用来得快吧. 下面请看一个SB的例子,重新编译以后,这个类在创建100,000,000实体时居然耗费了16秒的时间 ...

  3. 详细!交叉编译时 note: the mangling of 'va_list' has changed in GCC 4.4解决办法

    为什么要在标题前面加了详细两个字,就是为了吸引看文章的你还有写文章的我这种小白,我是从坑里面爬出来了. 废话少说.... 问题就是这样子了,至于解决办法,在网上搜索了很久,大多数以一段英文作为解决办法 ...

  4. windows 录音程序(二)

    (二)录音流程 Waveform APIs,流程如下: a.打开录音设备waveInOpen; b.准备wave数据头waveInPrepareHeader; c.准备数据块waveInAddBuff ...

  5. STAF no JSTAF in java.library.path 的终极解决办法

    最近两天在研究利用STAF 实现程序更新包的自动部署测试.运行Demo代码时遇到一个坑.我的安装路径是默认的.C:\STAF\samples\demo在命令行窗口用执行命令:java STAFDemo ...

  6. sql 注入的防范(一)

    为了保证程序的健壮性,我们必须对用户输入的数据做有效性验证,防止用户恶意提交数据. 关于防止 sql 注入 我主要从三个方面入手: 1.确认为正整数的,强制转化为int,$id  =$_GET('id ...

  7. java-内省与javabean

    JavaBean 是一种JAVA语言写成的可重用组件.为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器.JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性 ...

  8. php中explode与split的区别介绍

    php中explode与split的区别介绍 作者: 字体:[增加 减小] 类型:转载 今天在使用split时遇到一些问题.还是对函数理解不深刻,特写出来做个记 首先来看下两个方法的定义: 函数原型: ...

  9. [leetcode 34] search for a range

    1 题目: Given a sorted array of integers, find the starting and ending position of a given target valu ...

  10. 【腾讯Bugly干货分享】QQ电话适配iOS10 Callkit框架

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/58009392302e4725036142fc Dev Club 是一个交流移动 ...