Visual Studio中的debug和release版本的区别
VC编译开关选项分析(debug和release版本的对比)
VC编译开关选项分析(debug和release版本的对比)VC编译开关选项分析(debug和release版本的对比)1. 参考资源经常需要用到VC的编译开关,在网上搜索和在MSDN中找大体资源如下。
几乎所有的中文文章都是以这两个为基础发展来的。
Compiler Reference:/en-us/library/aa236704(v=VS.60).aspxCompiler Options Listed by Category:/en-us/library/aa236703(v=VS.60).aspx2. VC中默认的选择项如下所示:/nologo/MDd/W3/Gm/GX/ZI /Od/D "WIN32" /D "_DEBUG" /D "_WINDOWS"/D"_AFXDLL"/D "_MBCS" /FR"Debug/" /Fp"Debug/FTTnSystem.pch"/Yu"stdafx.h"/Fo"Debug/"/Fd"Debug/" /FD/GZ /c/nologo/MT/W3/GX/Zi /O2/D"WIN32" /D "NDEBUG" /D "_WINDOWS"/D"_MBCS"/FR"Release/"/Fp"Release/FTTnSystem.pch"/Yu"stdafx.h" /Fo"Release/"/Fd"Release/" /FD /c色块标识:Debug和Release都有 Debug Release3. 具体讲解在VC中debug版本中包含了很多调试信息,而release版本则是发布版,而这些信息都在编译开关中体现出来了。
c++ release debug编译
《深度探讨:C++ Release 和 Debug 编译的区别》在现今的软件开发行业中,C++ 语言作为一种经典而复杂的编程语言,一直以来都备受瞩目。
在 C++ 的编译过程中,Release 和 Debug 编译是两个极为重要的概念,它们对于软件的性能、稳定性和调试等方面都有着不可忽视的影响。
本文将从浅入深地探讨这两种编译方式的区别,以帮助读者更全面地理解 C++ 编译过程中的关键概念。
1. Release 和 Debug 编译概述让我们简要回顾一下 Release 和 Debug 编译的基本概念。
在 C++ 程序的编译过程中,Release 编译旨在生成优化后的可执行文件,以达到最佳性能和执行速度。
而 Debug 编译则注重在生成可执行文件的附带了调试信息,旨在为程序员提供更便捷、准确的调试功能。
2. Release 和 Debug 编译的差异接下来,我们来详细比较一下 Release 和 Debug 编译的主要差异。
在编译过程中,Release 编译会进行诸如函数内联、去除调试符号、优化代码等操作,以提高程序的执行效率和资源利用率。
而 Debug 编译则会保留调试信息、禁用优化等操作,以便于程序员在调试过程中准确地追踪变量、函数调用等信息。
3. Release 和 Debug 编译对程序性能的影响由于 Release 编译进行了大量的优化操作,因此生成的可执行文件往往具有更高的执行效率和更小的体积,适合部署到生产环境中。
而Debug 编译则由于保留了调试信息等,因此相对而言,生成的可执行文件会更大,执行效率较低,但却能够提供丰富的调试信息和功能。
4. 我对于 Release 和 Debug 编译的个人观点在我看来,Release 和 Debug 编译在实际开发中都具有其重要性。
Release 编译在保证程序性能的也能够节约资源,提高用户体验;而Debug 编译则在程序出现问题时,提供了必要的调试信息,有助于快速定位和修复 bug。
软件中Debug和Release到底有什么区别?
软件中Debug和Release到底有什么区别?有很多软件集成开发环境(IDE),比如VS(VC)、IAR等,在创建工程时都会自动生成有Debug 和 Release两个版本。
有些小伙伴比较纳闷,Debug 和 Release两个版本到底有什么区别?下面就来讲讲Debug 和 Release版本区别,及其相关的内容。
嵌入式专栏1关于Debug 和 Release版本Debug,顾名思义,就是调试版本;Release,即发布版本,或者说最终释放版本。
在一些项目中,会出现Debug 和 Release两个版本,比如:IAR EWARM:VS:一些初学者可能会问,他们二者到底什么差异?其实,Debug 和 Release两个版本其实主要就是工程配置不同。
我们这里拿IAR EWARM来说,主要是:Project -> Options 下面的配置选项不同:嵌入式专栏2Debug 和 Release差异Debug 和 Release两个版本,最根本的区别在于Debug版本多了一些与调试相关的配置内容。
1.生成调试信息Debug版本通常会生成调试信息,而Release通常没有这些信息。
比如IAR EWRAM:这里的“生成调试信息”其实包含了很多关于调试的信息,如果勾选会多出“.pbd”、 “.browse”、 “.linf”等与调试有关的信息。
补充①“.pbd”、 “.browse”为浏览信息的文件,“.linf”为链接配置相关的文件。
具体可以参看:IAR系列教程12_IAR文件类型描述。
补充②这个配置信息保存在“.ewp”(工程配置)文件下,包含了Debug 和 Release两个版本的配置信息:<configuration> <name>Debug</name> ...配置 </configuration><configuration> <name>Release</name> ...配置</configuration>你可以对比一下两个配置的差异,就知道二者的一些区别:补充③Keil MDK类似,也有类似的关于调试的配置:Projcet -> Options for Target:2.预处理Debug版本通常会有“DEBUG”相关的预处理(宏定义)不知道大家经常用类似下面的调试宏定义没有:#ifdef DEBUG //Debug调试版本相关的配置strongerHuang#else //Release发布版本相关的配置strongerHuang#endif比如最常见的就是printf(打印信息),会通过“DEBUG”调试信息打开/关闭打印输出信息。
VS中Debug模式和Release模式的区别
VS中Debug模式和Release模式的区别VS中Debug模式和Release模式的区别有些人可能会问VC中的Debug和Release模式到底有什么区别,能不能将两者混用。
这里是常见的看法:/en-US/vcgeneral/thread/775ce067-b225-4141-8b86-2d7e9b61db97/ syperk说:"Asaresult,I'veswitchedtocompilingmydebugbuildsusingthe/MD switch.Ifyoudothis,youalsohavetoundefinethe_DEBUGpreprocessormacro.O therwiseyougetlotsoferrorsabout_CrtDebugReportW()notfound.Thisfunctionis apparentlyinsertedintoyourcodeif_DEBUGisdefined,butisonlydefinedinthe debugCRT. Aslongasoptimizationisoffitseemstobeperfectlypossibletodebug programscompiledthisway,andtherearenoconcernsaboutCRTincompatibilit y.".但是他的说法并不完全正确。
混用有很多问题。
其中,最重要的一点是,混用通过不同的编译参数生成的模块是非常糟糕的做法,特别是涉及到条件编译的时候。
实际上,"Debug"和"Release"只是两套IDE预先设定好的编译参数和宏定义组合(例如我们经常遇到的_DEBUG和NDEBUG宏)。
编译器并不知道Debug和Release之分(不过MD和MDd编译参数会区分Debug版本和Release版本的运行时库)。
vs的命令参数
vs的命令参数全文共四篇示例,供读者参考第一篇示例:vs是微软公司推出的一款强大的集成开发环墶(IDE),被广泛用于开发各种类型的应用程序,例如Web应用程序、桌面应用程序、移动应用程序等。
在vs中,我们可以使用命令参数来执行一些特定的操作,比如编译代码、调试程序、部署项目等。
本文将介绍一些常用的vs命令参数,帮助开发人员更加高效地使用这个强大的开发工具。
1. /build:这个命令参数可以用来编译指定的解决方案或项目。
语法如下:devenv /build solution.sln。
这里的solution.sln表示要编译的解决方案的文件名。
如果不指定solution.sln,则会编译当前打开的解决方案。
3. /deploy:这个命令参数可以用来部署应用程序到指定的目标设备。
语法如下:devenv /deploy solution.sln/project:project.csproj /configuration:Debug /platform:x86。
这里的solution.sln表示要部署的解决方案的文件名,project.csproj表示要部署的项目文件名,configuration表示要部署的配置(Debug或Release),platform表示要部署的平台(x86、x64、AnyCPU等)。
7. /safemode:这个命令参数可以用来以安全模式启动vs,即在启动时禁用所有插件和扩展。
语法如下:devenv /safemode。
这样可以帮助排除插件和扩展可能导致的问题。
8. /?:这个命令参数可以用来查看vs的帮助文档。
语法如下:devenv /?。
这样可以查看所有可用的命令参数以及它们的用法和示例。
vs的命令参数可以帮助开发人员更加高效地使用这个强大的IDE,提高开发效率和质量。
开发人员可以根据自己的需要选择合适的命令参数来执行特定的操作,从而更好地完成开发任务。
希望本文介绍的vs命令参数对开发人员有所帮助,让他们更加熟练地使用这个优秀的开发工具。
[VC笔记]Debug和Release的困惑
[VC笔记]Debug和Release的困惑Lightning[0GiNr]PS:补充笔记,本文是在VC6的环境下编写的,VS2008无此BUG。
这些日子在写一些代码时遇到了一件令人非常囧的事情:同样的源码,DEBUG版本行为完全正常,RELEASE版本行为完全不正常。
按以往的经验,这一般都是#ifdef _DEBUG之类的宏导致了两个版本的行为不一致,但是我的程序中并没有显式或者隐式地使用过这个宏。
由于Release版本默认不支持调试,于是就把Release版本里挂上调试信息来试试。
在Project->Sittings的c/c++选项卡optimizations中选上Disable[DEBUG],Debug Info里填上Program Database,Link选项卡中搞定Generate debug info和Generate mapfile。
然后一按F5,行为完全和DEBUG版本一样正常!可是一换回默认的release,问题就会出现,狂郁闷……注释了几处代码,并且用printf输出了一些LOG后,我渐渐发现了问题所在:竟然是字符串操作的问题!为了便于说明,我先写一个例子:#include <windows.h>#include <stdio.h>int InsertString(char* pStr){strcpy(pStr, "world");return strlen(pStr);}int CreateString(char* pStr){strcpy(pStr, "Hello ");return strlen(pStr) + InsertString(pStr + strlen(pStr));}int main(void){char szHello[64] = "";int nLen = CreateString(szHello);printf("%s LEN = %d\n", szHello, nLen);system("pause");return 0;}你能猜出程序的输出是什么吗?DEBUG:RELEASE:数一下字符也知道,Release版本给出的LEN = 16是绝对错误的,问题出在CreateString函数的这一行:return strlen(pStr) + InsertString(pStr + strlen(pStr));在DEBUG版本或者加了调试信息的Release版中,VC编译器的编译结果是先计算加号左边的表达式,再计算右边的,这样,第一个strlen(pStr)计算的仅仅是"Hello "这个字符串的长度。
Debug和Realise版本
Debug与Release版本的区别Debug 和Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动。
如果我们愿意,我们完全可以把Debug和Release 的行为完全颠倒过来。
当然也可以提供其他的模式,例如自己定义一组编译选项,然后命名为MY_ABC等。
习惯上,我们仍然更愿意使用VC已经定义好的名称。
Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M)。
至于是否需要DLL支持,主要看你采用的编译选项。
如果是基于ATL的,则Debug和Release 版本对DLL的要求差不多。
如果采用的编译选项为使用MFC动态库,则需要MFC42D.DLL 等库支持,而Release版本需要MFC42.DLL支持。
Release不对源代码进行调试,不考虑MFC的诊断宏,使用的是MFC Release库,编译时对应用程序的速度进行优化,而Debug则正好相反,它允许对源代码进行调试,可以定义和使用MFC的诊断宏,采用MFC Debug库,对速度没有优化。
既然Debug和Release仅仅是编译选项的不同,那么为什么要区分Debug和Release 版本呢?Debug和Release,在我看来主要是针对其面向的目标不同的而进行区分的。
Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能力。
而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。
所以不保存调试信息,同时,它往往进行了各种优化,以期达到代码最小和速度最优。
为用户的使用提供便利。
下面仅就默认的Debug和Release版本的选项进行比较,详细的编译选项可以看MSDN 的说明。
我们将默认的Debug和Release的选项设置进行比较,过滤掉相同设置,主要的不同如下:编译选项:/Od /D "_DEBUG" /Gm /RTC1 /MDd /Fo"Debug““" /ZI链接选项:/OUT:"D:“MyProject“logging“Debug“OptionTest.dll" /INCREMENTAL Release设置:编译选项:/O2 /GL /D "NDEBUG" /FD /MD /Fo"Release““" /Zi链接选项:/OUT:"D:“MyProject“logging“Release“OptionTest.dll" /INCREMENTAL:NODebug 版本:/MDd /MLd 或/MTd 使用Debug runtime library(调试版本的运行时刻函数库)/Od 关闭优化开关/D "_DEBUG" 相当于#define _DEBUG,打开编译调试代码开关(主要针对assert函数)/ZI 创建Edit and continue数据库,在调试过程中如果修改了源代码不需重新编译/GZ 可以帮助捕获内存错误/Gm 打开最小化重链接开关,减少链接时间Release 版本:/MD /ML 或/MT 使用发布版本的运行时刻函数库/O1 或/O2 优化开关,使程序最小或最快/D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数)/GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改MDd与MD首先,Debug版本使用调试版本的运行时库(/MDd选项),Relase版本则使用的是发布版本的运行时库(vcrt.dll)。
如何使用VC++调试程序 VC调试快捷键 Debug版本与Release版本
1.如何在Release状态下进行调试Project->Setting=>ProjectSetting对话框,选择Release状态。
C/C++标签中的Category 选General,Optimizations选Disable(Debug),Debut info选Program Database。
在Link 标签中选中Generate debug info复选框。
注:只是一个介乎Debug和Release的中间状态,所有的ASSERT、VERIFY都不起作用,函数调用方式已经是真正的调用,而不查表,但是这种状态下QuickWatch、调用队列跟踪功能仍然有效,和Debug版一样。
2. Release和Debug有什么不同Release版称为发行版,Debug版称为调试版。
Debug中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。
Release版运行速度较快,可执行文件较小,但在其编译条件下无法执行调试功能。
Release的exe文件链接的是标准的MFC DLL(Use MFC in a shared or static dll)。
这些DLL在安装Windows的时候,已经配置,所以这些程序能够在没有安装Visual C++ 6.0的机器上运行。
而Debug版本的exe链接了调试版本的MFC DLL文件,在没有安装Visual C++6.0的机器上不能运行,因为缺相应的DLL,除非选择use static dll when link。
3. ASSERT和VERIFY有什么区别ASSERT里面的内容在Release版本中不编译,VERIFY里面的内容仍然翻译,但不再判断真假。
所以后者更安全一点。
例如ASSERT(file.Open(strFileName))。
一旦到了Release版本中,这一行就忽略了,file根本就不Open()了,而且没有任何出错的信息。
VisualStudio中的debug和release版本的区别
VisualStudio中的debug和relea se版本的区别Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
Debug 和 Release的真正秘密,在于一组编译选项。
下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Release版错误,在此不讨论)Debug 版本参数含义/MDd /MLd或/MTd使用 Debug runtime library (调试版本的运行时刻函数库)/Od 关闭优化开关/D "_DEBUG"相当于 #define_DEBUG,打开编译调试代码开关(主要针对ass ert函数)/ZI 创建 Edit and continu e(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译/GZ 可以帮助捕获内存错误/Gm打开最小化重链接开关,减少链接时间Release版本参数含义/MD /ML 或/MT 使用发布版本的运行时刻函数库/O1 或/O2 优化开关,使程序最小或最快/D "NDEBUG"关闭条件编译调试代码开关(即不编译ass ert函数)/GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改实际上,Debug 和 Release并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。
事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。
哪些情况下 Release版会出错有了上面的介绍,我们再来逐个对照这些选项看看 Release版错误是怎样产生的1、Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。
visul c++6.0的使用
一、Visual C++实验环境介绍1、Visual C++简介Visual C++是Microsoft公司的Visual Studio开发工具箱中的一个C++程序开发包。
VisualStudio提供了一整套开发Internet和Windows应用程序的工具,包括VisualC++, Visual Basic, Visual Foxpro, Visual InterDev, Visual J++以及其他辅助工具,如代码管理工具Visual SourceSafe和联机帮助系统MSDN。
Visual C++包中除包括C++编译器外,还包括所有的库、例子和为创建Windows应用程序所需要的文档。
从最早期的1.0版本,发展到最新的6.0版本,Visual C++已经有了很大的变化,在界面、功能、库支持方面都有许多的增强。
最新的6.0版本在编译器、MFC类库、编辑器以及联机帮助系统等方面都比以前的版本做了较大改进。
Visual C++一般分为三个版本:学习版、专业版和企业版,不同的版本适合于不同类型的应用开发。
实验中可以使用这三个版本的任意一种。
Visual C++集成开发环境(IDE)集成开发环境(IDE)是一个将程序编辑器、编译器、调试工具和其他建立应用程序的工具集成在一起的用于开发应用程序的软件系统。
Visual C++软件包中的Developer Studio就是一个集成开发环境,它集成了各种开发工具和VC编译器。
程序员可以在不离开该环境的情况下编辑、编译、调试和运行一个应用程序。
IDE中还提供大量在线帮助信息协助程序员做好开发工作。
Developer Studio中除了程序编辑器、资源编辑器、编译器、调试器外,还有各种工具和向导(如AppWizard和ClassWizard),以及MFC类库,这些都可以帮助程序员快速而正确地开发出应用程序。
向导(Wizard)向导是一个通过一步步的帮助引导你工作的工具。
项目Debug版本与Release版本的区别
项⽬Debug版本与Release版本的区别Debug版本:通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release版本:称为发布版本,它往往是进⾏了各种优化,使得程序在代码⼤⼩和运⾏速度上都是最优的,以便⽤户很好地使⽤。
实际上,Debug版本和 Release 并没有本质的界限,他们只是⼀组编译选项的集合,编译器只是按照预定的选项⾏动。
事实上,我们甚⾄可以修改这些选项,从⽽得到优化过的调试版本或是带跟踪语句的发布版本。
在Debug或Release⽂件夹中,通常会看到⼏种类型的⽂件:1、应⽤程序扩展类型⽂件:也就是dll⽂件(动态链接库);2、XML⽂档类型⽂件:此⽂件中保存的是dll⽂件中类、⽅法、参数等注释信息。
若没有此⽂件,在使⽤dll⽂件中的类和⽅法时,在intelisense中⽆法看到相应注释帮助信息;3、Program Debug Database【程序数据库】:a、序数据库⽂件保存着调试和项⽬状态信息,使⽤这些信息可以对程序的调试配置进⾏增量链接。
在使⽤ /Debug或/Release ⽣成时,会创建PDB ⽂件;b、以使⽤ /debug:full 或 /debug:pdb-only ⽣成应⽤程序。
使⽤ /debug:full ⽣成可调试的代码。
使⽤ /debug:pdbonly将产⽣PDB,但是不会产⽣通知JIT编译器调试信息可⽤的 DebuggableAttribute。
如果想⽣成的发布版本是不希望可调试的,那⽣成的PDB⽂件,请使⽤ /debug:pdb-only;c、isual Studio调试器使⽤EXE或DLL⽂件中的PDB路径查找 project.pdb⽂件。
如果调试器⽆法在该位置找到 PDB ⽂件,或者该路径⽆效,调试器将先搜索包含EXE的路径,然后搜索“选项”对话框中指定的符号路径。
该路径通常是“符号”节点中的“调试”⽂件夹。
如果调试器⽆法找到 .PDB ⽂件,则显⽰“查找符号”对话框,这将允许您搜索符号或向搜索路径添加其他位置;d、对Debug⽂件夹和Release⽂件夹中均有pdb,它们的不同在于:Debug中的pdb是full,保存着调试和项⽬状态信息,有断⾔、堆栈检查等代码;Release中的pdb是pdb-only,保存的信息也就是,出了什么错误以及错误在哪⾏;e、想在⽣成⽂件时不⽣成pdb⽂件,可在项⽬属性中的⽣成--⾼级--调试信息--选择none项就可以了;备注:个⼈认为在发布项⽬时,应该以Release⽅式来⽣成⽂件,同时以pdb-only的形式⽣成pdb⽂件,以备不时之需。
VC调试版(DebugVersion)和发行版(ReleaseVersion)
VC调试版(DebugVersion)和发⾏版(ReleaseVersion)调试是纠正或修改代码,使之可以顺利地编译、运⾏的过程。
为此,VC IDE提供了功能强⼤的调试和跟踪⼯具。
1.1.1 调试版(Debug Version)和发⾏版(Release Version)开发环境总是为你的⼯程创建调试版和发⾏版。
在调试版⾥,我们排查各种可能的程序错误,然后制作成发⾏版以获得较好的信息。
这就是调试版与发⾏版的区别:前者包含了较多调试信息,最终执⾏⽂件较⼤,性能较差;后者最终执⾏⽂件较⼩,性能更好。
具体地讲,发⾏版和调试版区别有:1. 调试版下,可以使⽤诊断和跟踪宏,如ASSERT和TRACE,MFC类的DUMP功能也定义在调试版下。
2. 额外的变量初始化。
编译器会⾃动将你未初始化的变量逐每字节赋值为0xCC。
3. 内存分配监视。
在调试版下,在堆上分配的内存都会记录,做额外的初始化(0xCD),在释放时,会将其内容逐字节置0xFD。
怎样配置调试版或发⾏版?调试版和发⾏版都可以从 Build | Configurations中增加,或者当这两个配置已存在的情况下,从Project | Settings命令下进⾏配置。
两者在配置上主要有以下不同:1. 两个版本应该配置成不同的输出⽂件夹。
这在Project | Settings | General中的两个编辑框中设定。
2. 调试版下,程序应该链接Debug版的c运⾏时库、禁⽌代码优化,并在C++属性页中的Preprocessor类别中加上预定义标识符_DEBUG。
在Link属性页中的Debug类别中,选中DebugInfo和Microsoft Format选框。
4. 发⾏版下,程序应该链接Release版的c运⾏时库、设置代码优化,不定义_DEBUG标识符,去掉DebugInfo选框中的选择。
1.1.2 排除编译错误VC6.0的编译器可以报告⼤约1100个左右的错误,这还不包含警告。
DebugBuild与ReleaseBuild的一些差别
status=WriteProcessMemory(processinfo.hProcess,(LPVOID)0x00403020,newdata,10,&bytewrite);
printf("\nWriteStatus:%x",status);
ResumeThread(processinfo.hThread);
if(bRes==0)
return0;
status=VirtualProtectEx(processinfo.hProcess,(LPVOID)0x004153d4,10,0x08,&oldprotect);
printf("\nProtectStatus:%x",status);
debugbuild和releasebuild在被CreateProcess装载出后,各自在.rdata和.data的memoryprotection是有所不同的。先看看debugbuild的。如果用CreateProcess把checkme的debugbuild装载后,检查textstring“Checkme!”的地址,发现memoryprotection是PAGE_READONLY(0x02)。读出没有问题,写入出错。代码如下:
printf("\nOldProtect:%x",oldprotect);
status=ReadProcessMemory(processinfo.hProcess,(LPVOID)0x004153d4,olddata,20,0);
printf("\nReadStatus:%x",status);
memset(&processinfo,0,sizeof(PROCESS_INFORMATION));
.netdebug和release的区别
.net debug和release的区别你知道.net debug指的是什么吗?release指的又是什么呢?两者之间有什么区别呢?下面就让店铺来告诉你.net debug和release的区别吧。
.net debug和release的区别一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 合并重复的字符串,并将字符串常量放到只读内存,防止被修改.net debug和release的区别二1. 变量。
大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc(注1),而release的赋值近似于随机(我想是直接从内存中分配的,没有初始化过)。
这样就明确了,如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成其他变量的不准确而引起其他的错误。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Visual Studio中的debug和release版本的区别Debug通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
Debug 和Release 的真正秘密,在于一组编译选项。
下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起Release 版错误,在此不讨论)Debug 版本参数含义/MDd /MLd或/MTd使用Debug runtime library (调试版本的运行时刻函数库)/Od 关闭优化开关/D "_DEBUG" 相当于#define _DEBUG,打开编译调试代码开关(主要针对assert函数) /ZI 创建Edit and continue(编辑继续)数据库,这样在调试过程中如果修改了源代码不需重新编译/GZ 可以帮助捕获内存错误/Gm打开最小化重链接开关,减少链接时间Release 版本参数含义/MD /ML 或/MT 使用发布版本的运行时刻函数库/O1 或/O2 优化开关,使程序最小或最快/D "NDEBUG" 关闭条件编译调试代码开关(即不编译assert函数)/GF 合并重复的字符串,并将字符串常量放到只读内存,防止被修改实际上,Debug 和Release 并没有本质的界限,他们只是一组编译选项的集合,编译器只是按照预定的选项行动。
事实上,我们甚至可以修改这些选项,从而得到优化过的调试版本或是带跟踪语句的发布版本。
哪些情况下Release 版会出错有了上面的介绍,我们再来逐个对照这些选项看看Release 版错误是怎样产生的1、Runtime Library:链接哪种运行时刻函数库通常只对程序的性能产生影响。
调试版本的Runtime Library 包含了调试信息,并采用了一些保护机制以帮助发现错误,因此性能不如发布版本。
编译器提供的Runtime Library 通常很稳定,不会造成Release 版错误;倒是由于Debug 的Runtime Library 加强了对错误的检测,如堆内存分配,有时会出现Debug 有错但Release 正常的现象。
应当指出的是,如果Debug 有错,即使Release 正常,程序肯定是有Bug 的,只不过可能是Release 版的某次运行没有表现出来而已。
2、优化:这是造成错误的主要原因,因为关闭优化时源程序基本上是直接翻译的,而打开优化后编译器会作出一系列假设。
这类错误主要有以下几种:1. 帧指针(Frame Pointer)省略(简称FPO):在函数调用过程中,所有调用信息(返回地址、参数)以及自动变量都是放在栈中的。
若函数的声明与实现不同(参数、返回值、调用方式),就会产生错误,但Debug 方式下,栈的访问通过EBP 寄存器保存的地址实现,如果没有发生数组越界之类的错误(或是越界“不多”),函数通常能正常执行;Release 方式下,优化会省略EBP 栈基址指针,这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。
C++ 的强类型特性能检查出大多数这样的错误,但如果用了强制类型转换,就不行了。
你可以在Release 版本中强制加入/Oy-编译选项来关掉帧指针省略,以确定是否此类错误。
此类错误通常有:MFC 消息响应函数书写错误。
正确的应为:afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);ON_MESSAGE 宏包含强制类型转换。
防止这种错误的方法之一是重定义ON_MESSAGE 宏,把下列代码加到stdafx.h中(在#include "afxwin.h"之后),函数原形错误时编译会报错。
#undef ON_MESSAGE#define ON_MESSAGE(message, memberFxn) \{message, 0, 0, 0, AfxSig_lwl, \(AFX_PMSG)(AFX_PMSGW)(static_cast< LRESULT (AFX_MSG_CALL \CWnd::*)(WPARAM, LPARAM) > (&memberFxn)},2. volatile 型变量:volatile 告诉编译器该变量可能被程序之外的未知方式修改(如系统、其他进程和线程)。
优化程序为了使程序性能提高,常把一些变量放在寄存器中(类似于register 关键字),而其他进程只能对该变量所在的内存进行修改,而寄存器中的值没变。
如果你的程序是多线程的,或者你发现某个变量的值与预期的不符而你确信已正确的设置了,则很可能遇到这样的问题。
这种错误有时会表现为程序在最快优化出错而最小优化正常。
把你认为可疑的变量加上volatile 试试。
3. 变量优化:优化程序会根据变量的使用情况优化变量。
例如,函数中有一个未被使用的变量,在Debug 版中它有可能掩盖一个数组越界,而在Release 版中,这个变量很可能被优化调,此时数组越界会破坏栈中有用的数据。
当然,实际的情况会比这复杂得多。
与此有关的错误有非法访问,包括数组越界、指针错误等。
例如:void fn(void){int i;i = 1;int a[4];{int j;j = 1;}a[-1] = 1;//当然错误不会这么明显,例如下标是变量a[4] = 1;}j 虽然在数组越界时已出了作用域,但其空间并未收回,因而i 和j 就会掩盖越界。
而Release 版由于i、j 并未其很大作用可能会被优化掉,从而使栈被破坏。
3. DEBUG 与NDEBUG :当定义了_DEBUG 时,assert() 函数会被编译,而NDEBUG 时不被编译。
此外,TRACE() 宏的编译也受_DEBUG 控制。
所有这些断言都只在Debug版中才被编译,而在Release 版中被忽略。
唯一的例外是VERIFY()。
事实上,这些宏都是调用了assert()函数,只不过附加了一些与库有关的调试代码。
如果你在这些宏中加入了任何程序代码,而不只是布尔表达式(例如赋值、能改变变量值的函数调用等),那么Release版都不会执行这些操作,从而造成错误。
初学者很容易犯这类错误,查找的方法也很简单,因为这些宏都已在上面列出,只要利用VC++ 的Find in Files 功能在工程所有文件中找到用这些宏的地方再一一检查即可。
另外,有些高手可能还会加入#ifdef _DEBUG 之类的条件编译,也要注意一下。
顺便值得一提的是VERIFY()宏,这个宏允许你将程序代码放在布尔表达式里。
这个宏通常用来检查Windows API的返回值。
有些人可能为这个原因而滥用VERIFY(),事实上这是危险的,因为VERIFY()违反了断言的思想,不能使程序代码和调试代码完全分离,最终可能会带来很多麻烦。
因此,专家们建议尽量少用这个宏。
4. /GZ 选项:这个选项会做以下这些事:1. 初始化内存和变量。
包括用0xCC 初始化所有自动变量,0xCD ( Cleared Data ) 初始化堆中分配的内存(即动态分配的内存,例如new ),0xDD ( Dead Data ) 填充已被释放的堆内存(例如delete ),0xFD( deFencde Data ) 初始化受保护的内存(debug 版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。
这样做的好处是这些值都很大,作为指针是不可能的(而且32 位系统中指针很少是奇数值,在有些系统中奇数的指针会产生运行时错误),作为数值也很少遇到,而且这些值也很容易辨认,因此这很有利于在Debug 版中发现Release 版才会遇到的错误。
要特别注意的是,很多人认为编译器会用0来初始化变量,这是错误的(而且这样很不利于查找错误)。
2. 通过函数指针调用函数时,会通过检查栈指针验证函数调用的匹配性。
(防止原形不匹配)3. 函数返回前检查栈指针,确认未被修改。
(防止越界访问和原形不匹配,与第二项合在一起可大致模拟帧指针省略FPO )通常/GZ 选项会造成Debug 版出错而Release 版正常的现象,因为Release 版中未初始化的变量是随机的,这有可能使指针指向一个有效地址而掩盖了非法访问。
除此之外,/Gm/GF等选项造成错误的情况比较少,而且他们的效果显而易见,比较容易发现。
怎样“调试” Release 版的程序遇到Debug成功但Release失败,显然是一件很沮丧的事,而且往往无从下手。
如果你看了以上的分析,结合错误的具体表现,很快找出了错误,固然很好。
但如果一时找不出,以下给出了一些在这种情况下的策略。
1. 前面已经提过,Debug和Release只是一组编译选项的差别,实际上并没有什么定义能区分二者。
我们可以修改Release版的编译选项来缩小错误范围。
如上所述,可以把Release 的选项逐个改为与之相对的Debug选项,如/MD改为/MDd、/O1改为/Od,或运行时间优化改为程序大小优化。
注意,一次只改一个选项,看改哪个选项时错误消失,再对应该选项相关的错误,针对性地查找。
这些选项在Project\Settings...中都可以直接通过列表选取,通常不要手动修改。
由于以上的分析已相当全面,这个方法是最有效的。
2. 在编程过程中就要时常注意测试Release 版本,以免最后代码太多,时间又很紧。
3. 在Debug 版中使用/W4 警告级别,这样可以从编译器获得最大限度的错误信息,比如if( i =0 )就会引起/W4 警告。
不要忽略这些警告,通常这是你程序中的Bug 引起的。
但有时/W4 会带来很多冗余信息,如未使用的函数参数警告,而很多消息处理函数都会忽略某些参数。
我们可以用:#progma warning(disable: 4702)//禁止//...#progma warning(default: 4702)//重新允许来暂时禁止某个警告,或使用#progma warning(push, 3)//设置警告级别为/W3//...#progma warning(pop)//重设为/W4来暂时改变警告级别,有时你可以只在认为可疑的那一部分代码使用/W4。
4. 你也可以像Debug一样调试你的Release版,只要加入调试符号。
在Project/Settings... 中,选中Settings for "Win32 Release",选中C/C++ 标签,Category 选General,Debug Info 选Program Database。