VC++ 编译过程
一 前言
一开始编译C++代码的时候可能会对编译的错误觉得很难理解,搞不清楚究竟是哪里错了。了解编译过程,能够更好的处理编译错误。
二 名词解释
编译单元:当一个c或cpp文件在编译时,预处理器首先递归包含头文件,形成一个含有所有 必要信息的单个源文件,这个源文件就是一个编译单元。
目标文件:目标文件包含着机器代码(可直接被计算机中央处理器执行)以及代码在运行时使用的数据,此外还包括其他调试信息。
三 编译过程
在VC中编译过程会分成以下三步:
1,预处理
2,生成目标文件
3,链接成可执行文件
1,预处理
将头文件加载进来,处理各种#define,如:宏,预编译条件,生成一个独立的编译单元。
可以通过以下的命令来生成独立的编译单元。
cl /EP test.cpp > test_p.cpp
这个命令的意思是,把源文件生成编译单元并写到test_p.cpp中。举个例子
下面是源文件代码
// test.cpp : Defines the entry point for the console application.
// #include "stdafx.h"
#include <windows.h>
#include <iostream> #define MAX(a,b) (a>b?a:b) #define PI 3.1415927 #ifdef UNICODE
typedef wchar_t MTCHAR;
#else
typedef char MTCHAR;
#endif // UNICODE
int _tmain(int argc, _TCHAR* argv[])
{
std::cout << MAX(, ) << std::endl;
std::cout << PI << std::endl;
MTCHAR *str = _T("hello world!");
_tprintf(_T("%s\n"), str);
return ;
}
源代码中包含了三个头文件,定义一个表达式的宏,一个常量的宏,和使用预编译条件定义了一个字符类型
我们通过上面的命令生成新的文件,包含文件指令会把头文件引进来,把宏在代码中替换掉,把预编译条件指令处理。
/*
这里省略掉大量的头文件代码,整个文件总共有三十多万行。
*/ typedef char MTCHAR; int main(int argc, _TCHAR* argv[])
{
std::cout << (>?:) << std::endl;
std::cout << 3.1415927 << std::endl;
MTCHAR *str = "hello world!";
printf("%s\n", str);
return ;
}
也可以在cl命令中加入宏UNICODE和_UNICODE,这样可以更清晰地看到预处理条件指令的处理效果
cl /EP /D "UNICODE" /D "_UNICODE" test.cpp > test_p.cpp
生成的编译单元
/*
这里省略掉大量的头文件代码,整个文件总共有三十多万行。
*/ typedef wchar_t MTCHAR; int wmain(int argc, _TCHAR* argv[])
{
std::cout << (>?:) << std::endl;
std::cout << 3.1415927 << std::endl;
MTCHAR *str = L"hello world!";
wprintf(L"%s\n", str);
return ;
}
MTCHAR已经被定义为wchar_t而不是char了,而且字符串也是wchar格式。
2,生成目标文件
将编译单元进行编译,生成目标文件(.obj文件)。这里通常分两个阶段:首先生成汇编语言,然后适用汇编生成机器码。
通过刚才生成的编译单元来生成目标文件
cl /c test_p.cpp
已经生成里机器码,所以不贴文件内容了。
3,链接
链接的任务就是把目标文件连起来生成可执行文件。
link test.obj
使用这个命令就能生成exe文件。
4,cl命令
cl命令有几个跟标准库有关的选项:/ML,/MLd,/MT,/MTd,/MD,/MDd。这些选项是想告诉编译器应用程序需要什么标准库。
/ML:(缺省选项)对应单线程静态的标准库。
/MT:对应多线程静态标准库 (libcmt.lib) ,此时编译器会自动定义 _MT 宏。
/MD:对应多线程 DLL 版 ( 导入库 msvcrt.lib , DLL 是msvcrt.dll) ,编译器自动定义 _MT 和 _DLL两个宏。
/MLd:对应调试单线程静态标准库 (libcd.lib) 。
/MTd:对应调试多线程静态标准库 (libcmtd.lib) 。
/MDd:对应调试多线程 DLL 标准库 ( 导入库msvcrtd.lib, DLL 是msvcrtd.dll) 。
最新文章
- 让所有的浏览器都支持html5
- perl 从文件里读出变量无法使用解决办法
- hdu---1024Max Sum Plus Plus(动态规划)
- js基础之arguments、css
- WINCE6.0远程桌面显示修改
- nfs文件系统挂载失败解决方法
- VoltDB公布4.0版本号,大步提高内存实时分析速度,进军操作数据库市场
- Node.js RESTful API
- 蟠桃记 AC 杭电
- wordpress在window下完美实现301重定向的方法
- OpenXml读取word内容(三)
- 小白的Python之路 day5 shutil模块
- day06深浅拷贝,元组,字典,集合
- JS-正则表达式 限制输入整数、小数
- Hadoop 电话通信清单
- 俄罗斯方块部分功能(Java)
- 关于4A(统一安全管理平台)系统的理解
- IO_ObjectOutputStream(对象的序列化)
- snmp 简单网管协议
- 安装和配置HyperServer
热门文章
- spring的作用及优势---第一个spring示例
- collection系列用法-defaultdict()
- C#中经常使用的几种读取XML文件的方法
- Windows内核之进程的终止和子进程
- Objective-C中的@dynamic
- xcode xib 加载 、注意点
- .Net C# ASP.Net和ADO.Net
- C#操作XML存取创建XML
- 交换机access和trunk的一些小结(转)
- java中对于JSON 的处理 fastjson gson 系统自带的JSON 的选择