转载请注明出处
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. 使用dom4j创建和解析xml文件

    使用dom4j创建和解析xml文件 在项目开发中,我们经常会遇到xml文件的创建和解析从别人接口得到的xml文件,而我们最常使用的组件是dom4j. 下面我就以代码来讲解一下如何使用dom4j来创建x ...

  2. angularjs 1.x $q模块使用

    什么是$q $q是angularjs1.x中内置服务,在需要使用时可以注入它. angular.module('app').controller('myController', function my ...

  3. monodevelop 突然莫名其妙的将 warning 全部标记为 error

    这是一个关于 monodevelop 的“坑” 我们在用 monodevelop 编译游戏脚本时, 通常会有一些警告,一般这些警告都是无害的, 不影响游戏运行.可是突然有一天, monodevelop ...

  4. arrayLiist的四种遍历方法

    package com.test; import java.util.ArrayList;import java.util.Iterator;import java.util.List; public ...

  5. cs程序添加初始化加载

    this.Name = "mysirst"; this.Text = "车辆窗体程序"; this.Load += new System.EventHandle ...

  6. hdu2604(递推,矩阵快速幂)

    题目链接:hdu2604 这题重要的递推公式,找到公式就很easy了(这道题和hdu1757(题解)类似,只是这道题需要自己推公式) 可以直接找规律,推出递推公式,也有另一种找递推公式的方法:(PS: ...

  7. Win7系统修改hosts文件不能保存的解决方法

    地址:http://jingyan.baidu.com/album/e5c39bf56564a539d7603312.html

  8. vpn找不到设备,win7建立新的VPN总时显示错误711,无法启动 Remote Access Connection Manager 及 Remote Access Auto Connection Manager 错误1068

    试试相关服务!一.remote access connection manager是网络连接的服务,它依赖于Technology服务,现在你的这个服务已经启动,而Secure Socket Tunne ...

  9. Hasor-Core v0.0.4 & Web v0.0.3 发布

    “Hasor是一款开源的 Java 应用开发框架.它是围绕 Guice 为核心创建的一系列模块组合而成.使用Hasor 会加快软件软件开发效率并降低开发成本.目前 Hasor包含了 Hasor-Cor ...

  10. Apache Marmotta 3.1.0-incubating 发布

    Apache Marmotta 3.1.0-incubating 发布了,Apache Marmotta 项目的目的是提供 Linked Data Platform 的开源实现,可让组织轻松的使用.扩 ...