VC++ 编译过程

2023-05-16

一 前言

一开始编译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) 。

转载于:https://www.cnblogs.com/luiszhao/p/4526636.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VC++ 编译过程 的相关文章

  • __FILE__,__LINE__,__DATE__,__TIME__ c++常用的预定义名字

    C 43 43 有四个常用的预定义名字 xff0c 分别为 FILE LINE DATE TIME FILE 记录文件的路径加名称 LINE 记录文件已经被编译的行数 DATE 记录文件的编译日期 TIME 记录文件的编译时间 可以当作变量
  • 串口拓展

    今天桌子下面找出一个破电路板看到一颗芯片GM8125 xff0c 这个芯片主要功能就是拓展串口 GM8125可以将一个全双工的标准串口扩展成5个标准串口 xff0c 并能通过外部引脚控制串口扩展模式 xff1a 单通道工作模式和多通道工作模
  • HttpUtils

    package com rs zero crc common http import com rs zero crc modulars common constants SysConstantConf import com xiaoleil
  • 【转】C语言中的位域、字节序、比特序、大小端

    1 比特序 位序 bit numbering bit endianness 我们知道一个字节有8位 xff0c 也就是8个比特位 从第0位到第7位共8位 比特序就是用来描述比特位在字节中的存放顺序的 通过阅读网页http en wikipe
  • 位定义方法定义寄存器

    寄存器 位域 定义的语法格式 xff1a Struct 位域结构名 类型说明符 位域名1 xff1a 位域长度 类型说明符 位域名2 xff1a 位域长度 类型说明符 位域名n xff1a 位于长度 从右到左申明的 位域的申明不能横跨两个字
  • Qt 模拟一个导航定位系统

    版权声明 xff1a 本文为博主原创文章 xff0c 遵循 CC 4 0 BY SA 版权协议 xff0c 转载请附上原文出处链接和本声明 本文链接 xff1a https www cnblogs com lihuidashen p 115
  • RESTful Api 身份认证中的安全性设计探讨

    REST 是一种软件架构风格 RESTful Api 是基于 HTTP 协议的 Api xff0c 是无状态传输 它的核心是将所有的 Api 都理解为一个网络资源 将所有的客户端和服务器的状态转移 xff08 动作 xff09 封装到 HT
  • 在STM32 MDK实现类似__attribute__((__packed__))效果

    attribute 是GNU C对标准C语法的扩展 xff0c 是GNU C的一大特色 xff0c 可以用于设置函数的属性 xff0c 变量的属性 xff0c 类型的属性 在STM32 MDK实现类似效果 xff1b 实验数据如下 xff1
  • 那些年搞不懂的多线程、同步异步及阻塞和非阻塞(一)---多线程简介

    1 进程和线程的概念 进程 xff1a 运行中的应用程序称为进程 xff0c 拥有系统资源 xff08 cpu 内存 xff09 线程 xff1a 进程中的一段代码 xff0c 一个进程中可以有多段代码 本身不拥有资源 xff08 共享所在
  • python爬虫登录保持及对http总结

    前言 这几天一直看python爬虫登录保持 实现接口太多 xff0c 太乱 xff0c 新手难免云山雾罩 各种get post xff0c 深入理解一下 xff0c 其实就是由于http的特性需要这些操作 http是一种无状态 不保存上次通
  • ROS CAN总线设备接入(一)Linux动态库的显式调用

    前提 xff1a xff08 1 xff09 xff0c 如果在libpcan安装正常的话 xff0c 那么可以用以下命令查找到libpcan so ls usr lib libpcan 查找到方可进行api载入 xff08 2 xff09
  • SQL Server 2012企业版和标准版的区别

    关于使用Microsoft SQL Server 数据库的公司一般会有疑问 xff0c 企业版数据库和标准版数据库的区别在哪 xff1f 如果采购企业版的价格和标准版的价格相差很大 xff0c 从多方资料查询发现 xff0c 我认为最主要的
  • 查询SQL SERVER 数据库版本号脚本语句

    数据库直接执行此语句即可 select 64 64 version 示例 xff1a Microsoft SQL Server 2014 12 0 2000 8 X64 Feb 20 2014 20 04 26 Copyright c Mi
  • SQL SERVER 还原误操作导致还原无法停止,处理办法

    昨天遇到运行库不知道单位哪个小伙子 xff0c 把数据库还原了 xff0c 导致单位业务全部瘫痪 xff0c 主数据库一直显示正在还原 xff0c 真的是不敢动 xff0c 经过多方寻找 xff0c 找到此脚本 数据库还原日志 xff0c
  • Docker安装及部署实例.Net Core

    1 什么是Docker Docker 是一个开源的应用容器引擎 xff0c 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中 xff0c 然后发布到任何流行的 Linux 机器上 xff0c 也可以实现虚拟化 容器是完全使用沙箱机制
  • 将html格式的内容转换成纯文本格式

    最近做的一个东东 xff0c 想要去除掉保存的字符串内容的所有html格式 xff0c 也就是只取纯文本 xff0c 从网上查了些相关资料 xff0c 以及正则表达式的用法 xff0c 有一个方法向大家推荐 xff0c 基本去除了我想要去除
  • 待解决:PDF header signature not found

    转载于 https www cnblogs com ITGirl00 p 3531475 html
  • 从统计学看线性回归(2)——一元线性回归方程的显著性检验

    目 录 1 2 的估计 2 回归方程的显著性检验 t 检验 xff08 回归系数的检验 xff09 F 检验 xff08 回归方程的检验 xff09 相关系数的显著性检验 样本决定系数 三种检验的关系 一 2 的估计 因为假设检验以及构造与
  • TypeError: unsupported operand type(s) for +: 'float' and 'decimal.Decimal'

    TypeError unsupported operand type s for 43 39 float 39 and 39 decimal Decimal 39 浮点型和双精度类型 相加报错 from decimal import Dec
  • 7.模块化封装Storage实现缓存数据持久化

    1 模块化封装Storage实现缓存数据持久化 1 在src目录下新建目录model xff0c 在model目录下新建js文件取名storage js var storage 61 set key value 设置为本地缓存方法 loca

随机推荐