在调试版本中遇到的一个问题是编译本地的C++应用程序。例如,许多局部变量消失了,因为代码生成器没有将它们放在堆栈上,而是将它们放在寄存器中,就像在调试生成中发生的那样。此外,release积极地构建对函数的内联调用,因此代码生成器将函数体直接放入调用方法中。一旦您习惯了编译器的模式,并了解了一点汇编语言,就不难理解在调试发行版生成代码时会发生什么。

我想在本文中介绍的是在不加应用程序的情况下正确创建本地C++发布PDB所必需的精确开关,这样我就可以回答隐形的问题了。我将向您展示的开关与优化无关,PDB文件的创建不会影响优化。
要设置的第一个开关是在编译器CL.EXE上,它是/Zi。此开关将调试信息放入.OBJ文件中,以便链接器将其放入最终PDB。您将在项目的C/C++属性页中设置这个开关。如下图

接下来的三个开关应用于链接器LINK.EXE。第一个命令/DEBUG告诉链接器您要为该生成创建PDB文件。如下:

/DEBUG开关有个小问题。打开它会告诉链接器您正在执行未优化的生成,所以/DEBUG隐式地打开/INCREMENTAL并实质上创建一个调试生成,尽管编译器优化会应用(但不是链接时代码生成优化)。这对您意味着链接器以“快速模式”链接,因此如果您的OBJ中有300个函数,但您只引用(即,使用)其中一个函数,那么链接器会将所有300个函数放入输出二进制文件中。是的,这意味着299个死函数和一个非常臃肿的二进制文件。这种“将所有内容都放入输出二进制文件”是调试版本比发布版本大得多的原因之一。微软的优化技术非常好,但不是那么好!
因为您只希望在输出二进制文件中实际引用那些函数,所以需要使用/OPT:REF开关将其告知链接器,该开关在链接器的优化部分中设置如下:

您需要设置的最后一个链接器开关是一个有趣的小gem:/OPT:ICF。这将打开COMDAT Folding。真 的!有一个术语你不是每天都听到。这是一个很好的小编译器优化,链接器将查找具有相同汇编语言代码的函数,并且只生成其中一个。这里的大多数人第一次谈到COMDAT的folding时,它会把它们扔出去循环。然而,当您考虑有多少函数,特别是简单且相同的STL模板时,这个COMDAT Folding可以帮助您精简二进制文件。如果仔细查看上面屏幕快照的优化部分,您将看到/OPT:ICF选项就在/OPT:REF选项的正下方。

发布构建二进制文件之所以增长,是因为没有设置/OPT:REF和/OPT:ICF开关。唯一的信息添加到一个本地C++二进制与这些开关是调试目录中的输出二进制。

正确创建本地C++发布构建PDBS的更多相关文章

  1. 使用Docker Toolbox 创建Docker虚拟机的方法-注意正确使用本地文件 file:参数的路径名

    使用Docker Toolbox 创建v1.12.6版的Docker虚拟机的方法, 一定要注意正确使用本地文件 file:// 参数的路径名, 之前尝试创建过多次,一直都没有成功过, 无法使用 fil ...

  2. git怎么创建本地版本仓库

    git怎么创建本地版本仓库 安装git我就不用说了吧!下载地址:https://github.com/msysgit/msysgit/releases/download/Git-1.9.4-previ ...

  3. 创建本地yum软件源,为本地Package安装Cloudera Manager、Cloudera Hadoop及Impala做准备

    一.包管理工具及CentOS的yum 1.包管理工具如何发现可以用的包 包管理工具依赖一系列软件源,工具下载源的信息存储在配置文件中,其位置随某包管理工具不同而变化 使用yum的RedHat/Cent ...

  4. 创建本地CM 离线服务器

    一.包管理工具及CentOS的yum 1.包管理工具如何发现可以用的包 包管理工具依赖一系列软件源,工具下载源的信息存储在配置文件中,其位置随某包管理工具不同而变化 使用yum的RedHat/Cent ...

  5. 使用WiX Toolset创建.NET程序发布Bootstrapper(安装策略管理)(一)——初识WiX

    原文:使用WiX Toolset创建.NET程序发布Bootstrapper(安装策略管理)(一)--初识WiX Visual Studio 打包安装七宗罪 开发.NET的人,肯定会使用Visual ...

  6. git 创建本地分支与远程分支

    早上抽空整理了下git常用操作,偶尔看看加深下印象吧: 如果github上已经有master分支 和dev分支 在本地 git checkout -b dev 新建并切换到本地dev分支 git pu ...

  7. 创建本地SVN版本库以及将SVN导入GIT

    创建本地SVN 通常SVN作为一种服务,是在服务器上架设,供用户通过网络访问使用.但如果只是自己日常使用,完全可以架设在本机上,不需要启动后台程序,通过文件的方式访问即可. 建立本地SVN非常简单,一 ...

  8. git拉取远程分支并创建本地分支

    本地分支推送至远程 git checkout local_branch git push origin local_branch:remote_branch 一.查看远程分支 使用如下Git命令查看所 ...

  9. 本地yum源构建以及Docker离线安装

    Docker离线安装以及本地yum源构建 在docker的使用过程中有时候会遇到一些私有化部署的问题,就是在一些无法上网的机器上面安装使用dokcer,这就引出了docker的离线安装的问题,dock ...

随机推荐

  1. Go基础编程实践(八)—— 系统编程

    捕捉信号 // 运行此程序,控制台将打印"Waiting for signal" // 按Ctrl + C 发送信号以关闭程序,将发生中断 // 随后控制台依次打印"Si ...

  2. Docker容器挂载文件(转载)

    一.Docker pull 安装 Nginx 1.查看docker仓库中的 nginx 命令 # 使用 docker search 命令搜索存放在 Docker Hub 中的镜像 docker sea ...

  3. 阿里巴巴 Java 开发手册 (十二)安全规约

    1. [强制]隶属于用户个人的页面或者功能必须进行权限控制校验. 说明:防止没有做水平权限校验就可随意访问.修改.删除别人的数据,比如查看他人的私信 内容.修改他人的订单. 2. [强制]用户敏感数据 ...

  4. Java自学-数组 Arrays

    java.util.Arrays类常用方法 Arrays是针对数组的工具类,可以进行 排序,查找,复制填充等功能. 大大提高了开发人员的工作效率. 步骤 1 : 数组复制 与使用System.arra ...

  5. Flutter — IDE Shortcuts for Faster Development

    https://medium.com/flutter-community/flutter-ide-shortcuts-for-faster-development-2ef45c51085b If yo ...

  6. 不安全的验证码Insecure CAPTCHA

    没啥好讲的,当验证不合格时,通过burp抓包工具修改成符合要求的数据包.修改参数标志位.USER-AGENT之类的参数. 防御 加强验证,Anti-CSRF token机制防御CSRF攻击,利用PDO ...

  7. 【开发工具】- Myeclipse10.7破解方法

    1.下载myeclipse 10,如果没有,可以使用链接:https://pan.baidu.com/s/1l9juqD4ALMuepVL6e5kgjA 密码:kpx6:当然时间久了可能链接失效,如有 ...

  8. WPF DataGrid 服务端排序

    转载:http://www.kecq.com/artic-10322303.html 以前做了一个数据客户端,不过是直接连数据库的,现在认为这种方式不太好,于是改成服务端RESTful API+客户端 ...

  9. centos7 docker安装nginx

    1.查询nginx最新镜像 docker search nginx 2.下载镜像 docker pull nginx 3.创建目录 mkdir -p /software/nginx/html mkdi ...

  10. MySQL主从复制什么原因会造成不一致,如何预防及解决?

    一.导致主从不一致的原因主要有: 人为原因导致从库与主库数据不一致(从库写入) 主从复制过程中,主库异常宕机 设置了ignore/do/rewrite等replication等规则 binlog非ro ...