C/C++编译过程理解【转】
转载自:http://www.cppblog.com/woaidongmao/archive/2008/11/07/66254.aspx
今天,通过自己的努力终于对C/C++的编译过程有了个粗略的了解,毕竟不想去翻《编译原理》这样的大部头书籍,但是又急于对编译的过程有个大概的了解,唉,这么多年来一直在苦苦挣扎,今天总算是对这个过程有了个大概的了解了。下面就说说我了解到的一些东西:
首先是预编译,这一步可以粗略的认为只做了一件事情,那就是“宏展开”,也就是对那些#***的命令的一种展开,例如define MAX 1000就是建立起MAX和1000之间的对等关系,好在编译阶段进行替换。例如ifdef/ifndef就是从一个文件中有选择性的挑出一些符合条件的代码来交给下一步的编译阶段来处理。这里面最复杂的莫过于include了,其实也很简单,就是相当于把那个对应的文件里面的内容一下子替换到这条include***语句的地方来。
其次是编译,这一步很重要,编译是以一个个独立的文件作为单元的,一个文件就会编译出一个目标文件。(这里插入一点关于编译的文件的说明,编译器通过后缀名来辨识是否编译该文件,因此“.h”的头文件一概不理会,而“.cpp”的源文件一律都要被编译,我实验过把.h文件的后缀名改为.cpp,然后在include的地方相应的改为***.cpp,这样一来,编译器就会编译许多不必要的头文件,只不过头文件里我们通常只放置声明而不是定义,因此最后链接生成的可执行文件的大小是不会改变的)清楚编译是以一个个单独的文件为单元的,这一点很重要,因此编译只负责本单元的那些事,而对外部的事情一概不理会,在这一步里,我们可以调用一个函数而不必给出这个函数的定义,但是要在调用前得到这个函数的声明(其实这就是include的本质,不就是为了给你提前提供个声明而好让你使用吗?至于那个函数到底是如何实现的,需要在链接这一步里去找函数的入口地址。因此提供声明的方式可以是用include把放在别的文件中的声明拿过来,也可以是在调用之前自己写一句void max(int,int);都行。),编译阶段剩下的事情就是分析语法的正确性之类的工作了。好啦,总结一下,可以粗略的认为编译阶段分两步:第一步,检验函数或者变量是否存在它们的声明;第二步,检查语句是否符合C++语法。
最后一步是链接,它会把所有编译好的单元全部链接为一个整体文件,其实这一步可以比作一个“连线”的过程,比如A文件用了B文件中的函数,那么链接的这一步会建立起这个关联。链接时最重要的我认为是检查全局空间里面是不是有重复定义或者缺失定义。这也就解释了为什么我们一般不在头文件中出现定义,因为头文件有可能被释放到多个源文件中,每个源文件都会单独编译,链接时就会发现全局空间中有多个定义了。
C/C++编译过程理解【转】的更多相关文章
- JavaScript预编译过程理解
1-JavaScript运行三部曲 语法分析 预编译 解释执行 语法分析很简单,就是引擎检查你的代码有没有什么低级的语法错误: 解释执行顾名思义便是执行代码了: 预编译简单理解就是在内存中开辟一些空间 ...
- 编译原理---antlr实践+编译过程理解+课程理解知识点
0.其他说明 0.0编译器分为前.中.后端,课上主要学的是前端.前端又分为词法分析(lexical analysis).语法分析(syntax analysis).语义分析(semantic anal ...
- CUDA 编程相关;tensorflow GPU 编程;关键知识点记录;CUDA 编译过程;NVCC
本文章主要是记录,cuda 编程过程中遇到的相关概念,名字解释和问题:主要是是用来备忘: cuda PTX :并行线程执行(Parallel Thread eXecution,PTX)代码是编译后的G ...
- 从编译,执行过程理解c#
上节我们说过C#所开发的程序源代码并不是编译成能够直接在操作系统上执行的二进制代码.与Java类似,它被编译成为中间代码,然后通过.NET Framework的虚拟机——被称之为通用语言运行时(CLR ...
- Android工程的编译过程
现在很多人想对Android工程的编译和打包进行自动化,比如建立每日构建系统.自动生成发布文件等等.这些都需要我们对Android工程的编译和打包有一个深入的理解,至少要知道它的每一步都做了什么,需要 ...
- android 编译过程
引用:http://www.cnblogs.com/devinzhang/archive/2011/12/20/2294686.html http://blog.sina.com.cn/s/blog_ ...
- [译]C++, Java和C#的编译过程解析
1.1.1 摘要 我们知道计算机不能直接理解高级语言,它只能理解机器语言,所以我们必须要把高级语言翻译成机器语言,这样计算机才能执行高级语言编写的程序,在接下来的博文中,我们将介绍非托管和托管语音的编 ...
- C程序编译过程
1.1程序被其他程序翻译成不同的格式 1.hello.c #include <stdio.h> int main() { printf("hello world\n") ...
- 【转】android程序编译过程
现在很多人想对Android工程的编译和打包进行自动化,比如建立每日构建系统.自动生成发布文件等等.这些都需要我们对Android工程的编译和打包有一个深入的理解,至少要知道它的每一步都做了什么,需要 ...
随机推荐
- Ruby on Rails Tutorial 第二章 之 微博资源
1.微博模型如下图所示: 2.创建微博资源,命令如下: $ rails generate scaffold Micropost content:text user_id:integer #生成微博资 ...
- oracle procedure存储过程(pl/sql)_使用declare cursor_begin end嵌套
create or replace procedure PRO_DelArticles ( ArticleId in varchar2 ) is ArticleNum varchar2(20); sq ...
- 用PC浏览器模拟手机浏览器(一):无扩展版
想浏览手机版,打开对应网址却跳转到PC版?怎么办? 下面咱们来说下在只是安装了浏览器,无需其他安装操作的情况下来怎么用PC浏览器模拟手机浏览器,然后访问手机站点. 浏览器众多,IE系列的咱就不考虑了, ...
- ArcGIS动态文本
处理动态文本 来自:http://resources.arcgis.com/zh-cn/help/main/10.2/index.html#/na/00s900000013000000/ Deskto ...
- 为什么arcgis里,鼠标的图标都变成放大镜不能用了
做作业做到一半,鼠标的图标就只有放大镜了,不管是点箭头还是作图工具都没用,手抓的也没用,只剩下放大镜的功能和图标了,这是怎么一回事啊?种情况我碰到过几次,具体原因不清楚,但是解决方法是有的:把你的数据 ...
- swift 中异常的处理方法
swift 中什么时候需要处理异常,在调用系统某个方法的时,该方法最后有一个throws 说明该方法会抛出异常,如果一个方法抛出异常,那么需要对该异常进行处理 swift 异常处理提供了三种方法 方式 ...
- python(1) -文件操作
很多时候我们需要对文件进行一些操作,比如读取并分析日志文件,写入日志文件等等.显然python也内置了对文件进行操作的函数. 读文件: >>> f = open('a.log','r ...
- activity工作的使用
一. 什么是工作流 以请假为例,现在大多数公司的请假流程是这样的 员工打电话(或网聊)向上级提出请假申请——上级口头同意——上级将请假记录下来——月底将请假记录上交公司——公司将请假录入电脑 采用工作 ...
- 类、对象以及jvm运行内存解析
一.JVM内存的分析: 第一步:存放在硬盘上的程序首先要被加载到内存空间中. 第二步:内存中的jvm找到程序中main函数作为入口,然后开始执行. 第三步:执行过程中的内存管理:内存分为四个部分: 栈 ...
- Eclipse+Axis自动生成Web Service WSDL文件
JDK版本:1.5.0_22 Eclipse版本:Helios Service Release 2(3.6.2) 首先创建一个web工程,创建过程如下: 如果选择Apache Tomcat v5.5, ...