码迷,mamicode.com
首页 > 编程语言 > 详细

VC++ 编译过程

时间:2015-05-24 23:16:45      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

一 前言

以前在编译C++代码的时候对编译的错误都觉得很难理解,搞不清楚究竟是哪里错了。后来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(10, 20) << std::endl;
    std::cout << PI << std::endl;
    MTCHAR *str = _T("hello world!");
    _tprintf(_T("%s\n"), str);
    return 0;
}

源代码中包含了三个头文件,定义一个表达式的宏,一个常量的宏,和使用预编译条件定义了一个字符类型

我们通过上面的命令生成新的文件,包含文件指令会把头文件引进来,把宏在代码中替换掉,把预编译条件指令处理。

/*
这里省略掉大量的头文件代码,整个文件总共有三十多万行。
*/

typedef char    MTCHAR;

int main(int argc, _TCHAR* argv[])
{
    std::cout << (10>20?10:20) << std::endl;
    std::cout << 3.1415927 << std::endl;
    MTCHAR *str = "hello world!";
    printf("%s\n", str);
    return 0;
}

也可以在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 << (10>20?10:20) << std::endl;
    std::cout << 3.1415927 << std::endl;
    MTCHAR *str = L"hello world!";
    wprintf(L"%s\n", str);
    return 0;
}

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++ 编译过程

标签:

原文地址:http://www.cnblogs.com/luiszhao/p/4526636.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!