VS中Debug和Realease、及静态库和动态库的区别整理

时间:2021-03-10 12:49:30

一、Debug和Realease区别产生的原因

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

Debug 和 Release 的真正区别,在于一组编译选项。

Debug 版本

参数 含义

/MDd /MLd 或 /MTd 使用 Debug runtime library(调试版本的运行时刻函数库)

/Od 关闭优化开关

/D "_DEBUG" 相当于 #define _DEBUG,打开编译调试代码开关(主要针对assert函数)

/ZI

创建 Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译

GZ 可以帮助捕获内存错误

Release 版本

参数 含义

/MD /ML 或 /MT 使用发布版本的运行时刻函数库

/O1 或 /O2 优化开关,使程序最小或最快

/D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数)

/GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改

Debug 和 Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。

相关经验: 转自http://dev.csdn.net/article/17/17068.shtm

二、Debug和Realease区别的表现

I. 内存分配问题

  1. 变量未初始化。下面的程序在debug中运行的很好。

thing * search(thing * something)

BOOL found;

for(int i = 0; i < whatever.GetSize(); i++)

{

if(whatever[i]->field == something->field)

{ /* found it /

found = TRUE;

break;

} /
found it */

}

if(found)

return whatever[i];

else

return NULL;

而在release中却不行,因为debug中会自动给变量初始化found=FALSE,而在release版中则不会。所以尽可能的给变量、类或结构初始化。

  1. 数据溢出的问题

如:char buffer[10];

int counter;

lstrcpy(buffer, "abcdefghik");

在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没有。但是在release版 中,counter可能被放在寄存器中,这样NULL就覆盖了buffer下面的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。

  1. DEBUG版和RELEASE版的内存分配方式是不同的 。如果你在DEBUG版中申请 ele 为 6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes为单位分配), 而在release版,分配给你的就是24bytes(release版以8bytes为单 位),所以在debug版中如果你写ele[6],可能不会有 什么问题,而在release版中,就有ACCESS VIOLATE。

    相关经验,转自http://www.cnblogs.com/JemBai/archive/2009/01/13/1374805.html

三、静态库和动态库的区别

静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持。
静态编译只需要所需的头文件和对应的lib库文件。
动态编译则需要所需的头文件、对应的lib库文件以及对应的dll库文件。
事实上,静态编译用到的库文件和动态编译用到的库文件有本质区别:前者静态库是一个或者多个obj文件的打包,所以有人干脆把从obj文件生成lib的过程称为Archive,即合并到一起。比如你链接一个静态库,如果其中有错,它会准确的找到是哪个obj有错,即静态lib只是壳子。而后者为动态连接库(DLL)的导入库,它告诉链接器调用的函数在哪个DLL中,函数执行代码在DLL中的什么位置,这也就是为什么需要附加依赖项 .LIB文件,它起到桥梁的作用。

四、VS中/MT、/MD、/MTd、/MDd的区别

1.Overview

目前,在VS中提供的运行时库分为静态链接库和动态链接库两类,而每一类运行时库又可再分为 debug 版和 release 版,因此VS共提供了 4 个运行时库。如下表:

C 运行时库                             库文件
MultiThread(static link) MT libcmt.lib
Debug multiThread(static link) MTd libcmtd.lib
MultiThread(dynamic link) MD msvert.lib
Debug multiThread(dynamic link) MDd msvertd.lib 2.各运行时库的区别 a.静态链接的多线程库

  静态链接的多线程库的目标代码也最终被编译在应用程序的二进制文件中,但是它可以在多线程程序中使用。通过 /MT 编译选项可以设置 Visual C++ 使用静态链接的单线程库。

  b.动态链接的运行时库

  动态链接的运行时库将所有的 C 库函数保存在一个单独的动态链接库 MSVCRTxx.DLL 中, MSVCRTxx.DLL 处理了多线程问题。使用 /MD 编译选项可以设置 Visual C++ 使用动态链接的运行时库。

  /MDd 或 /MTd 选项使用 Debug runtime library( 调试版本的运行时刻函数库 ) ,与 /MD 或 /MT 分别对应。 Debug 版本的 Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,加强了对错误的检测,因此在运行性能方面比不上 Release 版本。

3.运行时库的选择
根据最近的项目经验,如果项目中包含了其它编译好的lib静态库文件,就使用/MT。
总之要保持一致性。否则可能会出现链接错误:LINK2005或LINK2038等等。