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) 。
VC++ 编译过程的更多相关文章
- Qt打开外部程序和文件夹需要注意的细节(Qt调用VC写的动态库,VC需要用C的方式输出函数,否则MinGW32编译过程会报错)
下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this ...
- 3DSlicer源代码编译过程vs2008+windows xp [转]
一 下载QT源代码编译 1. 简述 在 Windows2000/xp/vista 下,安装 VS2008, QT 4.7.2 :并在 VS2008上建立 QT 的集成开发环境,利用 VS2008 ...
- VC编译连接选项详解
VC编译连接选项详解 大家可能一直在用VC开发软件,但是对于这个编译器却未必很了解.原因是多方面的.大多数情况下,我们只停留在“使用”它,而不会想去“了解”它.因为它只是一个工具,我们宁可把更多的精力 ...
- VC++ 编译libcurl 支持SSL,GZIP
由于网上下载的 libcurl 不支持 gzip,只好自己动手编译,期间走了很多弯路,下面是最终成功的记录. 我所使用的环境 Visual Studio 2010 . Windows 7 64 bit ...
- C/C++编译过程
C/C++编译过程 C/C++编译过程主要分为4个过程 1) 编译预处理 2) 编译.优化阶段 3) 汇编过程 4) 链接程序 一.编译预处理 (1)宏定义指令,如#define Name Token ...
- VC编译那些事儿
转载自:http://blog.csdn.net/wowolook/article/details/8077153 最近又被ms的编译选译纠结了一下,运行程序是老是弹出0x14b1 or 71 ...
- win10--vs2015--libjpeg--64位库的编译过程记录
win10--vs2015--libjpeg--64位库的编译过程记录 1. 下载源代码: http://libjpeg.sourceforge.net/ 或者 http://www.ij ...
- VC++编译说明
目录 第1章编译步骤 1 第2章编译源文件 2 2.1 编译器 2 2.2 包含头文件 3 2.3 重复包含 6 2.4 预编译头文件 7 2.4.1 创建 ...
- VC++ 编译libcurl 支持SSL,GZIP(有脚本)
由于网上下载的 libcurl 不支持 gzip,只好自己动手编译,期间走了很多弯路,下面是最终成功的记录. 我所使用的环境 Visual Studio 2010 . Windows 7 64 bit ...
随机推荐
- 程序猿的量化交易之路(20)--Cointrader之Assert实体(8)
转载需说明出处:http://blog.csdn.net/minimicall, http://cloudtrade.top 不论什么可交易的都能够称之为Assert,资产.其类代码例如以下: pac ...
- C++ TR1 置随机数种子
1. #include <stdlib.h> #include <random> #include <iostream> using namespace std; ...
- JavaScript引用类型之Array数组的排序方法
数组中已经存在两个JavaScript给我们定义好的重排序的方法:reverse()和sort()方法,下面来简单分析下: 1.reverse() 用于反转数组项的顺序,代码如下: <sc ...
- ##DAY10 UITableView基础
##DAY10 UITableView基础 UITableView继承于UIScrollView,可以滚动. UITableView的每⼀条数据对应的单元格叫做Cell,是UITableViewCel ...
- BZOJ 3439: Kpm的MC密码( trie + DFS序 + 主席树 )
把串倒过来插进trie上, 那么一个串的kpm串就是在以这个串最后一个为根的子树, 子树k大值的经典问题用dfs序+可持久化线段树就可以O(NlogN)解决 --------------------- ...
- C++学习之引用
C++学习之引用 临时变量.引用参数和const 现在,当参数为const引用的时候,如果实参与引用参数不匹配,C++将生成临时变量.C++将在下面两种情况下生成临时变 ...
- Servlet基础知识(一)——Servlet的本质
什么是Servlet: Servlet是运行在web服务器端(web容器,如tomcat)的程序,它与Applet相对,Applet是运行在客户端的程序. Servlet的主要作用是处理客户端的请求, ...
- Java的跨平台原理
JAVA的跨平台原理 JAVA的跨平台原理 Java是一种简单易用.完全面向对象.有平台无关性.安全可靠的.主要面向Internet的开发工具.Java自从1995年正式面世以来,它的快速发展已经使整 ...
- gulp+browserfy模块化工具环境搭建
1.下载ruby,在ruby环境下安装sass; 2.安装nodejs; 3.进入当前项目所在目录,在cmd命令行中输入npm install; 4.安装browserify和gulp 安装brows ...
- python 发送安全邮件
用python 写了一个发送邮件的脚本,配上host 和端口,发现一直报错: smtplib.SMTPException: No suitable authentication method foun ...