引用 VC++ Debug和Release区别
VC中Debug和Release的区别
vc中debug和release的不同在使用VC开发软件的过程中,正当要享受那种兴奋的时候突然发现:release与debug运行结果不一致,甚至出错,而release又不方便调试,真的是当头一棒啊,可是疼归疼,问题总要解决,下面将讲述一下我的几点经验,看看是不是其中之一:1. 变量。
大家都知道,debug跟release在初始化变量时所做的操作是不同的,debug是将每个字节位都赋成0xcc(注1),而release的赋值近似于随机(我想是直接从内存中分配的,没有初始化过)。
这样就明确了,如果你的程序中的某个变量没被初始化就被引用,就很有可能出现异常:用作控制变量将导致流程导向不一致;用作数组下标将会使程序崩溃;更加可能是造成其他变量的不准确而引起其他的错误。
所以在声明变量后马上对其初始化一个默认的值是最简单有效的办法,否则项目大了你找都没地方找。
代码存在错误在debug方式下可能会忽略而不被察觉到,如debug方式下数组越界也大多不会出错,在release中就暴露出来了,这个找起来就比较难了:( 还是自己多加注意吧2. 自定义消息的消息参数。
MFC为我们提供了很好的消息机制,更增加了自定义消息,好处我就不用多说了。
这也存在debug跟release的问题吗?答案是肯定的。
在自定义消息的函数体声明时,时常会看到这样的写法:afx_msg LRESULT OnMessageOwn(); Debug情况下一般不会有任何问题,而当你在Release下且多线程或进程间使用了消息传递时就会导致无效句柄之类的错误。
导致这个错误直接原因是消息体的参数没有添加,即应该写成:afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); (注2)3. release模式下不出错,但debug模式下报错。
这种情况下大多也是因为代码书写不正确引起的,查看MFC的源码,可以发现好多ASSERT 的语句(断言),这个宏只是在debug模式下才有效,那么就清楚了,release版不报错是忽略了错误而不是没有错误,这可能存在很大的隐患,因为是Debug模式下,比较方便调试,好好的检查自己的代码,再此就不多说了。
C++调试技巧
自己总是用VC平台来开发东西,但是有时候总是出这样那样的问题,在这里把Visual C++开发工具与调试技巧整理摘录如下,希望对大家有用,省去大家再去搜索的烦恼。
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))。
VC++6.0 Release和Debug的不同
/ d/ d 或 , T MD M【 l d使 用 D b grniel rr( 试 版本 的 运 行 (rdo” 所 以 注 意在 这 些 调 试 宏 的语 句 不 要 用 程序 相 关 变 量 如 i+ Ⅵ e u t bay调 u m i f j11。 、 0 + 写 时刻 函 数 库) 操作 的语句 。 E IY(是个例外。 V RF ) 顺便值得一提 的是 V R F 0宏 , E IY 这 / d关 闭 优 化 开 关 O 个 宏 允 许 你 将 程 序 代 码 放 在 布 尔 表 达 式 里 。 这 个 宏 通 常 用 来 检 查 / “ D B G”相 当 于 # e n DE UG打 开 编 译 调 试 代 码 开 关 D E U df e— B , i Wid w I的返 回值 。有些人可能为这个原因而滥用 V R F , no s AP E IY0 事
3 05 ) 0 2 0
【 摘 要 】 文 对 VC 编程 调 试 时 用 Rel 本 ae和 Deu s b g两 个版 本 的不 同之 处 做 了深 入 的 总 结 和 分析 。 【 键 词 】 Rel ; b g 编 译 关 VC; a eDeu ; s
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)。
VS中Debug模式和Release模式的区别
VS中Deb ug模式和Relea se模式的区别有些人可能会问VC中的Debug和Rele ase模式到底有什么区别,能不能将两者混用。
这里是常见的看法:/en-US/vcgene ral/thread/775ce067-b225-4141-8b86-2d7e9b61db97/ syperk说:"Asares ult,I'veswit chedt ocomp iling mydeb ugbui ldsus ingth e/MDswit ch.Ifyoud othis,youals ohave tound efine the_D EBUGp repro cesso rmacr o.Otherw iseyo ugetl otsof error sabou t_Crt Debug Repor tW()notfou nd.Thisfu nctio nisap paren tlyin serte dinto yourc odeif_DEBU Gisde fined,butiso nlyde fined inthe debug CRT. Aslong asopt imiza tioni soffi tseem stobe perfe ctlyp ossib letod ebugp rogra mscom piled thisw ay,andthe reare nocon cerns about CRTin compa tibil ity.".但是他的说法并不完全正确。
混用有很多问题。
其中,最重要的一点是,混用通过不同的编译参数生成的模块是非常糟糕的做法,特别是涉及到条件编译的时候。
OSG在VS2008下的配置安装心得
在XP(32位)安装OSG2.8.2。
安装心得如下:一、准备安装资料包括程序(请到官方网站都可以下载)1. OpenSceneGraph-2.8.2.zip (源程序包)2. cmake-2.8.3-win32-x86.zip (安装源代码需要的工具)3. OpenSceneGraph-Data-2.8.0.zip (数据文件包)4. 3rdParty_VC9sp1_x86_x64.7z (第三方插件库:WINDOWS支持的图形库)(问题:详细作用)(rdParty只是一个统称,通常指的是某个软件所依赖的所有其它软件的集合。
例如,界面图形接口库Qt依赖于libjpeg,libmng,libpng,freetype等多种第三方库,以实现各种图形和字体格式的支持。
由于这些第三方库的存在,Qt不需要再额外编写和测试图形文件读写的代码,并且相应的功能可以随着这些第三方库的更新而更新,十分方便且稳定。
而OpenSceneGraph的第三方库主要用于实现各种模型、图形、字体文件的读写,如果需要某种格式的支持,请首先下载相应的第三方库(例如ttf格式对应freetype,hdr格式对应OpenEXR等)源代码,使用您自己的编译器生成第三方库的链接文件(DLL,LIB等),再编译OSG的对应插件;有些第三方库也会直接提供编译好的链接库文件,可以直接使用。
)友情提示:其中1、3、4可在下载,2可在/cmake/resources/software.html或/files下载,注意在下载过程中与自己使用的VC版本相对应,比如VS2008的为VC9。
二、安装过程:1. 为了统一方面,在D盘新建一个OSG目录(根据自己的情况放置),并将源程序包解压到此目录。
将各压缩包程序也解压到指定目录:D:\OSG\OpenSceneGraph (放置OSG库文件)D:\OSG\3dParty (放置图形库)D:\OSG\Data (放置演示等例子和数据)2. 用CMake生成Project & Solution files。
VC调试方法
VC所依赖的开发平台Microsoft Developer Studio本身提供的调试功能并不弱,每当我们创建一个新的VC工程项目时,默认状态就是Debug(调试)版本,在"组建"(Build)菜单下的Configurations中可以看到除了调试版本还可以设置成发行(Release)版本。
调试版本由于包含了大量信息,所以它生成的可执行程序容量会远远大于发行版。
具体地,调试版本主要增加了两个内容:其一,会执行编译命令_D_DEBUG,使头文件的调试语句ifdef及其代码附加到程序中;其二,在可执行文件中加入的调试信息使开发人员能够观察变量,进行单步执行等。
在VC"组建"(Build)菜单下的"开始调试"中有4条专用的调试命令:Go,Step into,Run to Cursor,Attach to process…。
在运行程序源代码时用Go命令(而不是Execute)才能处于调试状态, Go命令会使程序运行变得缓慢下来,但可以更好地控制运行程序,我们可以在任何时刻中断程序、单步执行、查看变量、检查调用栈。
有必要详细介绍一下VC的调试功能:首先,再次强调要用Go命令运行一个将要调试的程序;如果要中止调试状态下的运行程序可以点击Stop Debugging命令,还可以通过Break选项以可恢复方式中断调试程序的运行流程(用Restart选项可以重新开始运行程序);Step Into选项表示每次只执行一行语句(单步执行),但如果当前代码是调用一个函数,那么Step Into表示进入该函数,全部函数语句执行完后返回,而Step Over则是跳出这个函数;Step To Cursor选项表示程序将执行到光标所在的可执行语句行上;在调试多线程程序时,可以在线程函数或主应用程序线程中设置断点,还可以用Break选项结束线程后用Threads选项查看运行线程列表,也可以选择悬挂和恢复每个线程;在设置断点后,在VC "查看"菜单的"调试窗口"中可以查看变量、内存、调用堆栈、寄存器以及反汇编语句。
深入了解Debug和Release的区别
深⼊了解Debug和Release的区别⼀:Bin ⽬录⽤来存放编译的结果,bin是⼆进制binrary的英⽂缩写,因为最初C编译的程序⽂件都是⼆进制⽂件,它有Debug和Release两个版本,分别对应的⽂件夹为bin/Debug和bin/Release,这个⽂件夹是默认的输出路径,我们可以通过:项⽬属性—>配置属性—>输出路径来修改。
obj是object的缩写,⽤于存放编译过程中⽣成的中间临时⽂件。
其中都有debug和release两个⼦⽬录,分别对应调试版本和发⾏版本,在.NET中,编译是分模块进⾏的,编译整个完成后会合并为⼀个.DLL或.EXE保存到bin⽬录下。
因为每次编译时默认都是采⽤增量编译,即只重新编译改变了的模块,obj保存每个模块的编译结果,⽤来加快编译速度。
是否采⽤增量编译,可以通过:项⽬属性—>配置属性—>⾼级—>增量编译来设置。
PRoperties⽂件夹定义你程序集的属性项⽬属性⽂件夹⼀般只有⼀个 AssemblyInfo.cs 类⽂件,⽤于保存程序集的信息,如名称,版本等,这些信息⼀般与项⽬属性⾯板中的数据对应,不需要⼿动编写。
.cs 类⽂件。
源代码都写在这⾥,主要就看这⾥的代码。
.resx 资源⽂件,⼀些资源存放在这⾥,⼀般不需要看。
.csproj C#项⽬⽂件,⽤VS打开这个⽂件就可以直接打开这个项⽬,⾃动⽣成,不需要看。
er 是⼀个配置⽂件,⾃动⽣成的,会记录项⽬⽣成路径、项⽬启动程序等信息。
也不需要看。
.Designer.cs 设计⽂件,⾃动⽣成,不需要看。
.aspx 是⽹页⽂件,HTML代码写在这⾥⾯。
sln:在开发环境中使⽤的解决⽅案⽂件。
它将⼀个或多个项⽬的所有元素组织到单个的解决⽅案中。
此⽂件存储在⽗项⽬⽬录中.解决⽅案⽂件,他是⼀个或多个.proj(项⽬)的集合 *.sln:(Visual Studio.Solution) 通过为环境提供对项⽬、项⽬项和解决⽅案项在磁盘上位置的引⽤,可将它们组织到解决⽅案中。
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:链接哪种运行时刻函数库通常只对程序的性能产生影响。
VC-Debug-Release出错的问题解决办法
DEBUG和RELEASE 版本差异及调试相关问题: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];elsereturn NULL;而在release中却不行,因为debug中会自动给变量初始化found=FALSE,而在release版中则不会。
所以尽可能的给变量、类或结构初始化。
2. 数据溢出的问题如:char buffer[10];int counter;lstrcpy(buffer, "abcdefghik");在debug版中buffer的NULL覆盖了counter的高位,但是除非counter>16M,什么问题也没有。
但是在release版中,counter可能被放在寄存器中,这样NULL就覆盖了buffer下面的空间,可能就是函数的返回地址,这将导致ACCESS ERROR。
3. DEBUG版和RELEASE版的内存分配方式是不同的。
如果你在DEBUG版中申请ele 为6*sizeof(DWORD)=24bytes,实际上分配给你的是32bytes(debug版以32bytes为单位分配),而在release版,分配给你的就是24bytes(release版以8bytes为单位),所以在debug版中如果你写ele[6],可能不会有什么问题,而在release版中,就有ACCESS VIOLATE。
keil的几种编译模式
keil的几种编译模式Keil是一款广泛使用的嵌入式开发工具,提供了多种编译模式来满足不同的开发需求。
下面我将介绍几种常见的Keil编译模式。
1. Debug模式,Debug模式是开发过程中常用的编译模式之一。
在Debug模式下,编译器会生成额外的调试信息,以便在调试过程中能够准确地定位和跟踪代码。
这些调试信息包括符号表、源代码行号等。
Debug模式编译的程序运行速度较慢,但方便开发者进行程序调试和错误排查。
2. Release模式,Release模式是用于最终发布产品的编译模式。
在Release模式下,编译器会进行优化,以提高程序的执行效率和减小程序的体积。
一般会关闭调试信息的生成,并进行各种优化,如代码压缩、函数内联、无用代码删除等。
Release模式编译的程序运行速度较快,但不便于调试。
3. Simulator模式,Simulator模式是一种在模拟器上运行程序进行调试的编译模式。
在这种模式下,编译器会生成适用于模拟器的可执行文件,而不是直接在目标硬件上运行。
这样可以方便地在没有硬件设备的情况下进行调试和验证。
4. RAM模式,RAM模式是一种将程序加载到RAM中运行的编译模式。
在这种模式下,编译器会将程序的代码和数据都加载到RAM 中,从而提高程序的执行速度。
RAM模式适用于一些对实时性要求较高的应用,如实时控制系统。
5. ROM模式,ROM模式是一种将程序加载到ROM中运行的编译模式。
在这种模式下,编译器会将程序的代码和常量数据存储在ROM中,而将变量数据存储在RAM中。
这样可以节省RAM的使用,适用于资源有限的嵌入式系统。
这些是Keil常见的几种编译模式,开发者可以根据具体的需求选择合适的模式来进行开发和调试。
C++中时间与时间戳的转换
C++中时间与时间戳的转换C++中时间与时间戳的转换C语言把括号、赋值、强制类型转换等都作为运算符处理。
从而使C语言的运算类型极其丰富,表达式类型多样化。
下面是店铺分享的C++中时间与时间戳的转换,一起来看一下吧。
C++ 中时间与时间戳的转换实例// 设置时间显示格式:NSString *timeStr = @"2011-01-26 17:40:50";[formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制。
//设置时区,这个对于时间的处理有时很重要。
//例如你在国内发布信息,用户在国外的另一个时区,你想让用户看到正确的发布时间就得注意时区设置,时间的换算。
//例如你发布的时间为2010-01-26 17:40:50,那么在英国爱尔兰那边用户看到的时间应该是多少呢?//他们与我们有7个小时的时差,所以他们那还没到这个时间呢...那就是把未来的事做了。
NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];[formatter setTimeZone:timeZone];NSDate *date = [formatter dateFromString:timeStr]; //------------将字符串按formatter转成nsdateNSLog(@"date = %@", date);NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式NSLog(@"datenow = %@", datenow);NSString *nowtimeStr = [formatter stringFromDate:datenow];//----------将nsdate按formatter格式转成nsstring,nsstring会显示与当前的时间吻合的串NSLog(@"nowtimeStr = %@", nowtimeStr);// 时间转时间戳的方法:NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];NSLog(@"timeSp:%@",timeSp); //时间戳的值// 时间戳转时间的方法NSDate *confromTimesp = [NSDate dateWithTimeIntervalSince1970:1296035591];NSLog(@"1296035591 = %@",confromTimesp);NSString *confromTimespStr = [formatter stringFromDate:confromTimesp];NSLog(@"confromTimespStr = %@",confromTimespStr);// 时间戳转时间的方法:NSDateFormatter* formatter1 = [[NSDateFormatter alloc] init];[formatter1 setDateStyle:NSDateFormatterMediumStyle];[formatter1 setTimeStyle:NSDateFormatterShortStyle];[formatter1 setDateFormat:@"yyyyMMddHHMMss"];NSDate *date1 = [formatter1 dateFromString:@"1283376197"];NSLog(@"date1:%@",date1);当前时间是:14:41:57C/C++内存管理内存分配方式简介在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。
Debug版本下能运行而Release下不能运行的问题总结
Debug版本下能运⾏⽽Release下不能运⾏的问题总结引⾔如果在您的开发过程中遇到了常见的错误,或许您的Release版本不能正常运⾏⽽Debug版本运⾏⽆误,那么我推荐您阅读本⽂:因为并⾮如您想象的那样,Release版本可以保证您的应⽤程序可以象Debug版本⼀样运⾏。
如果您在开发阶段完成之后或者在开发进⾏⼀段时间之内从来没有进⾏过Release版本测试,然⽽当您测试的时候却发现问题,那么请看我们的调试规则1:规则1: 经常性对开发软件进⾏Debug和Release版本的常规测试. 测试Release版本的时间间隔越长,排除问题的难度越⼤,⾄少对Release版本进⾏每周1不要随意删除ReleaseASSERT和TRACE在Release 例如: ASSERT(m_ImageList.Create(MAKEINTRESOURCE(IDB_IMAGES), 16, 1, RGB(255,255,255))); 这样的代码在Debug模式不会出错,图像列表也⾃动创建了,然⽽在Release版本呢?后继使⽤m_ImageList对象只会造成程序的Crash!,因此ASSERT宏中尽量使⽤逻辑运算符作为验证。
规则 2: 不要将代码放置在仅在某种编译选项中执⾏的地⽅,对于使⽤_DEBUG等编译选项宏内部的代码必须不影响整个程序的使⽤。
规则 3: 不要使⽤规则2作为评判标准来删除ASSERT宏,ASSERT宏是个有⽤的⼯具,但容易使⽤错误. 使Debug编译模式接近Release模式如果您的Release版本存在的问题是由代码被编译器⾃动排除造成的,那么通过这个⽅法您的问题可能会重现. ⼀些问题的产⽣可能是由于不同编译选项之间预定义符号造成的,因此您可以更改编译模式下的预定义符号,从⽽使您的Debug模式接近Release模式,观察错误是否产⽣, 更改编译预定义符号⽅法如下: a.. Alt-F7打开项⽬设置,在C++/C 页⾯,选择"General"类别,更改"_DEBUG"符号为"NDEBUG".b.. 在C++/C 页⾯, 选择"Preprocessor"类别,添加预定义符号"_DEBUG"到"Undefined Symbols"栏.c.. 使⽤"Rebuild All"重新编译如果通过上⾯设置,您在Release编译模式下⾯的问题在Debug模式下重现,那么请您依据以下步骤对您的代码进⾏修改: a.. 查找ASSERT排除其中的所有重要执⾏语句,或者将ASSERT修改为VERIFY. b.. 检查"#ifdef _DEBUG" 内所有代码,排除Release模式使⽤的代码. c.. 查找TRACE 排除其中的所有重要执⾏语句. TRACE和ASSERT⼀样,仅在Debug模式下编译. 如果通过上⾯修改更正了您在Debug模式下的问题,那么您可以重新编译Release模式,⾮常有可能您可以解决先前存在的问题!. 错误的假定造成编译模式错误您是否经常性的假定您的变量或者对象被初试化成某个指定的值(可能0)?您是否假定你所有关联到的资源在应⽤程序中都存在?这些也是Debug和Release模式下不同问题产⽣的原因。
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)向导是一个通过一步步的帮助引导你工作的工具。
如何解决VISUAL C++ 6.0不正确连接的问题
Part1:1. 如何解决Visual C++ 6.0不正确连接的问题情景:明明改动了一个文件,却要把整个项目全部重新编译链接一次。
刚刚链接好,一运行,又提示重新编译链接一次。
这是因为出现了未来文件(修改时间和创建时间比系统时间晚)的缘故。
可以这样处理:找到工程文件夹下的debug目录,将创建和修改时间都比系统时间的文件全部删除,然后再从新“Rebuild All”一次。
2. 引起LNK2001的常见错误都有哪些遇到的LNK2001错误主要为:unresolved external symbol “symbol”如果链接程序不能在所有的库和目标文件内找到所引用的函数、变量或标签,将产生此错误信息。
一般来说,发生错误的原因有两个:一是所引用的函数、变量不存在,拼写不正确或者使用错误;其次可能使用了不同版本的链接库。
以下是可能产生LNK2001错误的原因:<1>由于编码错误导致的LNK2001错误(1)不相匹配的程序代码或模块定义(.DEF)文件导致LNK2001。
例如,如果在C++源文件了内声明了一变量“var1”,却试图在另一个文件内以变量“var1”访问改变量。
(2)如果使用的内联函数是在.cpp文件内定义的,而不是在头文件内定义将导致LNK2001错误。
(3)调用函数时如果所用的参数类型和头函数声明时的类型不符将会产生LNK2001错误。
(4)试图从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001错误。
(5)要注意函数和变量的可公用性,只有全局变量、函数是可公用的。
静态函数和静态变量具有相同的使用范围限制。
当试图从文件外部方位任何没有在该文件内声明的静态变量时将导致编译错误或LNK2001错误。
<2>由于编译和联机的设置而造成的LNK2001错误(1)如果编译时使用的是/NOD(/NODERAULTLIB)选项,程序所需要的运行库和MFC时将得到又编译器写入目标文件模块,但除非在文件中明确包含这些库名,否则这些库不会被链接进工程文件。
VS2008 解决方案的目录结构设置和管理
/tech/devlodoc/C/?page=2VC 2008 解决方案的目录结构设置和管理一个中等规模的解决方案通常都会包含多个项目,其中一些项目产出静态库,一些产出动态库,一些用于单元测试,还有的产出最终的应用程序执行档。
除此以外,根据项目的需求,还会使用一些第三方的库。
所以为解决方案设置一个合理的目录结构,不但可以使得代码管理更井井有条,项目成员之间也更容易相互配合,更重要的是能够使得最终应用程序的安装包制作,源代码打包发布和转移变得十分容易。
解决方案与项目:从VC6之后VC系列就使用解决方案(Solution)来替代原来的工作空间,用于组织和管理多个相关的项目(Project)。
文章首先演示一个虚拟的解决方案和我们期望得到的目录结构,然后使用VC2008的项目设置功能来一步一步达到我们的需求。
虚拟解决方案:该虚拟解决方案名为GMA,包含一个动态链接库项目ChocolateMilk和一个应用程序项目PureMilk,需要使用一个第三方库log4cxx(Apache log4j的C++移植版本,用于日志输出)。
log4cxx是以动态库的方式编译的,所以我们需要它的3样东西,分别是头文件,导入库(log4cxx.lib, log4cxxd.lib)和动态链接库(log4cxx.dll)。
假设我们期望的目录结构如下图:1. GMA是解决方案目录2. PureMilk和ChocolateMilk是项目目录3. Lib目录用于存放导入库或者静态库(包括第三方库和自己的项目)4. Include用于存放第三方库的头文件5. Bin目录存放所有动态链接库和执行档,包括自己的产出和第三方库,区分Release和Debug两个版本。
另外,程序运行过程中需要外部的数据文件和启动时需要的配置文件等等都可放于该目录6. Temp用于存放临时生成文件,其中Compile存放编译器编译时生成的obj文件,Link存放链接器的输出文件。
vc++各文件扩展名
.C:用C语言编写的源代码文件。
.CLW:ClassWizard生成的用来存放类信息的文件。classwizard信息文件,ini文件的格式。
.CNT:用来定义帮助文件中“Contents”的结构。
.CPP或.CXX:用C++语言编写的源代码文件。
.CUR:光标资源文件。
.DEF:模块定义文件,供生成动态链接库时使用。
.PLG:编译信息文件,编译时的error和warning信息文件。
.RC:资源定义文件。
.RC2:资源定义文件,供。
.RES:二进制资源文件,资源编译器编译资源定义文件后即生成RES文件。
.RTF:Rich Text Format(丰富文本格式)文档,可由Word或写字板来创建,常被用来生成Help文件。
pch:预编译头文件;
res:资源文件;
.APS:存放二进制资源的中间文件,VC把当前资源文件转换成二进制格式,并存放在APS文件中,以加快资源装载速度。资源辅助文件。
.BMP:位图资源文件。
.BSC:浏览信息文件,由浏览信息维护工具(BSCMAKE)从原始浏览信息文件(.SBR)中生成,BSC文件可以用来在源代码编辑窗口中进行快速定位。用于浏览项目信息的,如果用source brower的话就必须有这个文件。可以在project options里去掉Generate Browse Info File,这样可以加快编译进度。
.PBI、.PBO和.PBT:由VC的性能分析工具PROFILE生成并使用的三种文件。
.PCH:预编译头文件,比较大,由编译器在建立工程时自动生成,其中存放有工程中已经编译的部分代码,在以后建立工程时不再重新编译这些代码,以便加快整个编译过程的速度。
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个左右的错误,这还不包含警告。
Visual C++ 6.0 - 工程设置解读
VC6.0的工程设置解读Project--Settings 做开发差不多一年多了,突然感觉对VC的工程设置都不是很清楚,天天要和VC见面,虽然通常情况下一般都不会修改工程设置,但是还是有必要对它的一些设置项的来龙去脉有一定的了解,所以狂查资料,稍作整理,总结一篇文档,方便以后查阅,总得记录点什么,温故而知新嘛。
进入工程设置界面有两种方法:方法一,选择法:【Project】->【Settings】方法二,快捷键:【Alt+F7】打开工程设置对话框,如下图:左边的列表可以选择要设置的工程编译方式(Debug或Release),如果多个工程,还可以选择要设置的工程。
右边是一个属性页,内容十分丰富,依次是:General , Debug , C/C++ , Link , Resource , MIDL , Browse Info , Custom Build , Pre-link Step , Post-build step下面主要介绍各个选项的功能:【General】设置工程的一般特性。
1.Microsoft Foundation Classes 连接MFC静态库的方式,默认为共享的DLL方式,对一些不支持MFC42的机器环境来说,选择静态编译还是有必要的。
2.Intermediate files 中间文件输出路径,比如:*.obj、*.pch、*.res、*.sbr、*.idb、*.pdb3.Output files 输出文件路径,比如:*.exe。
4.Allow per-configuration dependencies 按外部制作文件(exported makefile)方式为每个工程配置导出不同的可建立项目。
【Debug】设置工程调试的选项。
Category 选项种类,先看看General种类选项卡1.Executable for debug session 如果是dll的工程,需要指定启动它的exe文件路径,如果是exe工程,默认当前工程路径。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
引用VC++ Debug和Release区别2009-12-17 09:53--------------------------------------本文主要包含如下内容:1. Debug 和 Release 编译方式的本质区别2. 哪些情况下 Release 版会出错2. 怎样"调试" Release 版的程序--------------------------------------一、Debug 和 Release 编译方式的本质区别Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
Debug 和 Release 的真正秘密,在于一组编译选项。
下面列出了分别针对二者的选项(当然除此之外还有其他一些,如/Fd /Fo,但区别并不重要,通常他们也不会引起 Rele ase 版错误,在此不讨论)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 时不被编译。
除此之外,VC++中还有一系列断言宏。
这包括:ANSI C 断言 void assert(int expression );C Runtime Lib 断言 _ASSERT( booleanExpression );_ASSERTE( booleanExpression );MFC 断言 ASSERT( booleanExpression );VERIFY( booleanExpression );ASSERT_VALID( pObject );ASSERT_KINDOF( classname, pobject );ATL 断言 ATLASSERT( booleanExpression );此外,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 ) 初始化受保护的内存(de bug 版在动态分配内存的前后加入保护内存以防止越界访问),其中括号中的词是微软建议的助记词。
这样做的好处是这些值都很大,作为指针是不可能的(而且 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,或运行时间优化改为程序大小优化。