Debug 运维不荒谬,Release版本无法平常运维总括(转)

引言

    
若是在你的费用进度中境遇了广阔的不当,恐怕你的Release版本不可能符合规律运转而Debug版本运转无误,那么本身推荐你读书本文:因为不用如您想象的那样,Release版本能够确定保证你的应用程序能够象Debug版本一样运转。

假使您在开发阶段实现以往依然在开发展开一段时间之内一向不曾进展过Release版本测试,可是当你测试的时候却发现难点,那么请看大家的调剂规则1:

规则1:

  平日性对开发软件实行Debug和Release版本的健康测试.
测试Release版本的时间距离越长,排除难题的难度越大,至少对Release版本进行周周一次的测试,能够使您在紧凑的开发周期内节省潜在的排故时间.
不要轻易删除Release版本须求的代码那一点看起来就像再鲜明然而,但却是开发人士无意中时常犯的失实,原因在于编写翻译器编写翻译Release版本时候会积极性化解在代码中存在的宏,例如ASSE途观T和TRACE在Release版本会自动清除,那样造成的难点是你在这么些宏当中运作的代码也被随后删除,那是不行危急的作业J,例如:
ASSE君越T(m_ImageList.Create(MAKEINTRESOURCE(IDB_IMAGES), 16, 1,
奥迪Q3GB(255,255,255)));
那样的代码在Debug方式不会出错,图像列表也自动成立了,可是在Release版本呢?后继使用m_ImageList对象只会造成程序的Crash!,由此ASSETucsonT宏中尽量采取逻辑运算符作为表明。

规则 2:

  
不要将代码放置在仅在某种编写翻译选项中实施的地点,对于使用_DEBUG等编写翻译选项宏内部的代码必须不影响整个程序的行使。

规则 3:

  不要采纳规则2当做评判标准来删除ASSEXC90T宏,ASSESportageT宏是个有效的工具,但简单选拔错误.
使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.. 查找ASSEPRADOT排除个中的装有重庆大学实践语句,可能将ASSE福特ExplorerT修改为VELANDIFY. b..
检查”#ifdef _DEBUG” 内全数代码,排除Release格局应用的代码. c..
查找TRACE 排除当中的有注重要实践语句.
TRACE和ASSERAV4T一样,仅在Debug情势下编写翻译.
假使经过上边修改修正了您在Debug形式下的问题,那么你能够再次编译Release形式,相当有大概您可以消除先前留存的标题!.
错误的比方造成编译格局错误你是或不是常常性的只要你的变量只怕目的被初试化成有些钦命的值(只怕0)?您是不是假定你有所涉嫌到的能源在应用程序中都存在?这几个也是Debug和Release形式下区别难点时有产生的原故。

规则 4:

  除非您在代码中对变量举行开端化,不然不可能作出如上假定.
包涵全局变量,自动变量,申请对象和new对象.
这种情状还常常发生在内部存储器顺序的题材,记得原来采纳结构体的时候为了使用方便,比较多少个结构体对象使用memcmp,在Debug版本工作平常,而Release版本总括出错误的解,看来确实不能够开始展览不当的比方!

规则 5:

  确认保障删除财富的有所引用都被剔除,例如resource.h中的定义.
软件开发中,差异编写翻译版本对变量和内部存款和储蓄器的先河化是见仁见智的.
如若你假设变量开头化为0,那么在Win9x系统的Release格局下,会出现分外现象。因而对负有变量,内部存款和储蓄器显式清0是较为安全的做法.
即使您引用了早已被去除的能源,您的Debug版本能够健康工作,不过Release版本大概会crash.
您是否相信编写翻译器? 编写翻译器警告级别和编译噪音有着一定大的关系.
通过升高编写翻译器警告级别可扩展程序隐藏难点暴光的机会.平日设置警示级别在”Level
3″只怕 “Level
4”.编写翻译并消除全部警告,那是公布Release版本应用程序的二个很好的建议.那能揭露会使你的应用程序出现难题的广大发轫化难题和别的潜在的错误.

规则 6:

  开头项目事先先将编写翻译警告级别设置在”Level 3″ 或然 “Level 4”
,登记代码在此之前确认保障消灭全体警告!.
总结报告编写翻译格局下的调节曾经不止2遍的视听一些VC开发者说Release格局上面不能够举办调剂,幸运的是:通过相应设置,能够在Release情势开始展览调节,因而那只不过是1个谬种流传的不当说法而已。

 规则 7:

  当前面全数的方法都不算的时候,在Release格局下边进行调节和测试.
Release情势可以进行调剂,第2步是开拓符号表: a..
Alt-F7开拓项目设置,在C++/C 页面,选取”General”类,修改Debug Info
setting 为 “Program Database”. b.. 在”Link” 页面,选取”Generate Debug
Info”. c.. “Rebuild All”
这几个设置将允许你在Release方式下保留符号表,您也足以同时考虑以下设置: a..
调节和测试Release版本应用程序,您能够关闭优化选项. b..
如若在Release方式上面不能安装断点,添加指令”__asm {int 3}”
能够使你的应用程序在该行结束(鲜明在公布应用程序时候解除那几个代码).
在Release方式开始展览调节的多少个限制. a..
最大的难题在于你无法跟踪到MFC函数内部,原因在于Release版本的MFC动态链接库不包涵调节和测试消息和标记表.
b.. 同上,想要调节和测试调用的dll,您必须给它们整个丰硕调试消息和标志表.
编写翻译器生成了不当的代码?
大概有个别时候你会发现VC++编写翻译器生成了’难题代码’,但是坦率的讲,人们常见抱怨的太早.您能够在Release格局下边关闭优化增选来进展测试.
假设那些操作消除了你的难题,只怕你的编码习惯存在难题. 信不信由你,
极其可能在你的编码中留存意马心猿的求解也许看起来如同正确,有个别原则下也是正确的意况.
举个例子,上边包车型客车代码在Debug形式就像整个’正常’,而在Release情势下边却会出错!
#include int* func1(){int retval = 5;return &retval;} int main(int
argc, char* argv[]){printf(“%d/n”, *func1());return
0;}我信任大多数程序员特别是初学者简单境遇此类情状的。

规则 8:

  如若关闭Release方式的优化增选能够使你的应用程序运营符合规律化,而打开优化增选则出现难点的化,原因多半在于你的不良编码习惯造成的.
这意味必须仔细检查你的代码,清理出那么些错误的借使,悬空指针等等.
等同的那告诉您,在Debug格局和倒闭优化增选的Release形式下您的应用程序工作例行全是因为系统包含的运气,您必须伊始改正存在隐患的代码,不然在其后只怕会促成巨大的损失。

 规则 9:

  尽管您曾经绝望反省了您的代码,并且没有察觉标题,那么您最佳各种打开优化增选将生出错误的来头限制在某些范围之内.
BTW- 以上难点代码由C++编写翻译器自动物检疫出. 若是您已经依据 规则 6
您或然在头里环节中早已缓解了这个难点.
凭自己的支付经历,编写翻译器极少会生出错误的代码(当然要专注接口程序边界对齐的难题).平常在使用模板类时候VC6编写翻译器可能会发生断言ASSEEvoqueT错误,那种情形你只需立异补丁即可化解。

     
最终的想想在经常编码中只需稍微扩充某个严厉的检查和测试,便能有效的制止新的Debug
-v- Release情势难点的爆发,以下是本身的局地经历。

     1. 取出(check out)须要修改的代码。

     2. 修改代码,排除拥有警告,编写翻译Debug和Release版本.

     3.
详实地度量试新代码,即单步调节和测试新代码段之后进入工作代码,确定保证代码无误.

     4. 改良全体失水准.

     5. 确认无误之后将新代码登记入库(check in).

     6.
对注册入库的代码进行全新的编译,确认保障新登记代码与其他代码融合.

     7. 再次详细测试代码.

     8. 改正新难题(恐怕能够窥见登记入库代码存在的题材)
严厉依照以上步骤,您在筹划开发进度中即可缓解大气标题,防止在最后发布应用程序时候发生新的不便稳定的难题.

  后记本文是在自家的支出进度中遇见Release版本应用程序发表,发生错误的时候苦苦求索获得的一些经验,原来的书文来自于codeproject,经过自身润色,改写成为适合国内开发者的稿子,希望能对大家有用,谢谢!
转发:
Debug版本包含调节和测试音讯,所以要比Release版本大很多(恐怕大数百K至数M)。至于是还是不是要求DLL协理,首要看你采取的编写翻译选项。即使是依据ATL的,则Debug和Release版本对DLL的供给大致。假诺运用的编写翻译选项为运用MFC动态库,则供给MFC42D.DLL等库辅助,而Release版本须求MFC42.DLL扶助。Release
Build不对源代码进行调剂,不考虑MFC的诊断宏,使用的是MFC
Release库,编写翻译十对应用程序的进度举行优化,而Debug
Build则刚刚相反,它同意对源代码举办调剂,能够定义和平运动用MFC的诊断宏,选取MFC
Debug库,对速度没有优化。

  • 一 、Debug 和 Release 编译方式的本质分化 Debug
    平常号称调节和测试版本,它含有调试消息,并且不作任何优化,便于程序员调试程序。Release
    称为发布版本,它往往是展开了各类优化,使得程序在代码大小和平运动转速度上都以最优的,以便用户很好地行使。
    Debug 和 Release
    的真正秘密,在于一组编写翻译选项。下边列出了独家指向两岸的取舍(当然除却还有别的部分,如/Fd
    /Fo,但差距并不主要,平时他们也不会滋生 Release 版错误,在此不研商)
    Debug 版本: /MDd /MLd 或 /MTd 使用 Debug runtime
    library(调节和测试版本的周转时刻函数库) /Od 关闭优化开关 /D “_DEBUG”
    相当于 #define _DEBUG,打开编译调试代码开关(主要针对 assert函数)
    /ZI 创造 艾德it 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 断言 ATLASSE大切诺基T( booleanExpression ); 其余,TRACE()
      宏的编写翻译也受 _DEBUG 控制。 全部这一个断言都只在
      Debug版中才被编译,而在 Release 版中被忽略。唯一的不等是
      VE奥德赛IFY() 。事实上,这几个宏都以调用了 assert()
      函数,只可是附加了部分与库有关的调节和测试代码。如若您在这个宏中参预了别样程序代码,而不只是布尔表明式(例如赋值、能改变变量值的函数调用
      等),那么 Release
      版都不会履行那个操作,从而导致错误。初学者很简单犯那类错误,查找的主意也很简短,因为那么些宏都已在地点列出,只要采用VC++ 的 Find in Files
      作用在工程具备文件中找到用那么些宏的地方再相继检查即可。此外,某个高手可能还会加盟
      #ifdef _DEBUG 之类的规范编写翻译,也要留心一下。 顺便值得一提的是
      VE路虎极光IFY()
      宏,这几个宏允许你将程序代码放在布尔表明式里。那个宏平日用来检查
      Windows API 的重回值。有些人或然为那些原由此滥用 VE宝马X3IFY()
      ,事实上那是危急的,因为 VELacrosseIFY()
      违反了断言的构思,不能够使程序代码和调剂代码完全分开,最后大概会拉动许多困苦。因而,专家们提议尽量少用那么些宏。 4.
      /GZ 选项:那一个选项会做以下那么些事 (1) 伊始化内部存款和储蓄器和变量。包蕴用
      0xCC 伊始化全部活动变量,0xCD ( Cleared Data )
      伊始化堆中分红的内部存款和储蓄器(即动态分配的内部存款和储蓄器,例如 new ),0xDD ( Dead
      Data ) 填充已被放走的堆内存(例如 delete ),0xFD( deFencde Data
      ) 起先化受保险的内部存款和储蓄器(debug
      版在动态分配内部存款和储蓄器的光景投入保养内部存款和储蓄器避防止越界访问),在那之中括号中的词是微软建议的助记词。那样做的利益是那几个值都非常大,作为指针是不大概的(而且
      三拾九个人系统中指针很少是奇数值,在稍微系统中奇数的指针会生出运营时不当),作为数值也很少遭逢,而且那一个值也很简单辨认,由此那很有益在
      Debug 版中窥见 Release
      版才会遇到的失实。要尤其注意的是,很多少人以为编写翻译器会用 0
      来早先化变量,那是漏洞百出的(而且那样很不方便人民群众查找错误)。 (2)
      通过函数指针调用函数时,会由此检查栈指针验证函数调用的匹配性。(防止原形不匹配) (3)
      函数再次来到前检查栈指针,确认未被涂改。(幸免越界访问和真相不兼容,与第叁项合在一起可大致模拟帧指针省略
      FPO ) 日常 /GZ 选项会导致 Debug 版出错而 Release
      版不奇怪的气象,因为 Release
      版中未初步化的变量是随便的,这有可能使指针指向一个卓有成效地址而掩盖了不法访问。
      除此而外,/Gm /GF
      等选拔造成错误的意况相比少,而且她们的功效鲜明,相比较简单发觉。
      在选取VC开发软件的进程中,正当要分享那种兴奋的时候突然发现:
      release与debug运转结果不雷同,甚至出错,而release又不便民调节和测试,真的是1头一棒啊,然则疼归疼,难题总要化解,上边将讲述一下自个儿的两点经历,看看是还是不是中间之一: 1.
      变量。我们都知情,debug跟release在开端化变量时所做的操作是区别的,debug是将每一个字节位都赋成0xcc,而release的赋值近似于随机(作者想是直接从内部存储器中分红的,没有初步化过,但debug为啥不是0xff或0x00或其余什么的就不得而知了)。那样就精通了,假使您的主次中的有个别变量没被开头化就被引用,就很有恐怕出现万分:用作控制变量将招致流程导向不平等;用作数组下标将会使程序崩溃;尤其大概是致使任何变量的不准确而引起其余的荒谬。所以在宣称变量后随即对其起头化叁个默许的值是最简便易行实用的方法,不然项目大了您找都没地点找。代码存在不当在debug情势下可能会忽视而不被发现到,如debug格局下数组越界也大抵不会出错,在release中就展表露来了,这几个找起来就比较难了:(
      依然自个儿多加留心吧 2. 自定义音讯的新闻参数。
      MFC为我们提供了很好的音信机制,更充实了自定义音信,好处我就绝不多说了。那也设有debug跟release的题材啊?答案是自然的。在自定义信息的函数体注脚时,时常会看到这么的写法:afx_msg
      LRESULT OnMessageOwn();
      当你在二十八线程或进程间采纳了音信传递时就会促成无效句柄之类的错误。这一个缘故便是信息体的参数没有添加,即应当写成:afx_msg
      LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam);
      (具体原因小编也不太明白,是还是不是因为调用时按着暗中同意的参数多分配了WPARAM+LPARAM的空间而损坏了应用程序的内部存款和储蓄器空间?还请权威多携带)
      防止的情势: 1. 在意变量的开端化 2. 自定义音信的正式写法 3.
      使用调试语句TRACE等时利用后最佳注释掉 4. 不择手段利用try –
      catch(…) VE安德拉IFY 和 ASSECRUISERT
      的差距:三个在Release下边能够执行,3个不得以 DEBUG和RELEASE
      版本差距及调节和测试相关题材: 内部存款和储蓄器分配难点 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中却11分,因为debug中会自动给变量初叶化found=FALSE,而在release版中则不会。所以尽量的给变量、类或组织开始化。 2.
      数目溢出的标题 如:char buffer[10]; int counter;
      lstrcpy(buffer, “abcdefghik”);
      在debug版中buffer的NULL覆盖了counter的上位,不过除非counter>16M,什么难点也未曾。不过在release版中,counter大概被放在寄存器中,那样NULL就覆盖了buffer下边包车型客车上空,或者正是函数的回来地址,那将造成ACCESS
      EOdysseyROQX56。 3. DEBUG版和RELEASE版的内部存款和储蓄器分配办公室法是例外的
      。假如您在DEBUG版中申请 ele 为
      6*sizeof(DWO索罗德D)=24bytes,实际上分配给您的是32bytes(debug版以32bytes为单位分配),
      而在release版,分配给您的就是24bytes(release版以8bytes为单位),所以在debug版中只要你写ele[6],大概不会有哪些难点,而在release版中,就有ACCESS
      VIOLATE。 II. ASSE奇骏T和VEENVISIONIFY 1.
      ASSE哈弗T在Release版本中是不会被编译的。 ASSE哈弗T宏是这样定义的
      #ifdef _DEBUG #define ASSERT(x) if( (x) == 0)
      report_assert_failure() #else #define ASSERT(x) #endif
      实际上复杂一些,但无所谓。若是你在这么些语句中加了先后中必须求某些代码
      比如 ASSE中华VT(pNewObj = new CMyClass); pNewObj->MyFunction();
      那种时候Release版本中的pNewObj不会分配到空间
      所以执行到下二个口舌的时候程序会报该程序执行了违规操作的荒唐。这时能够用VE福睿斯IFY
      : #ifdef _DEBUG #define VERIFY(x) if( (x) == 0)
      report_assert_failure() #else #define VERIFY(x) (x) #endif
      那样的话,代码在release版中就足以推行了。 III. 参数难题:
      自定义新闻的处理函数,必须定义如下: afx_msg LRESULT
      OnMyMessage(WPARAM, LPARAM);
      重返值必须是HRESULT型,否则Debug会过,而Release出错 IV. 内部存款和储蓄器分配
      保险数据创立和扫除的统一性:倘使二个DLL提供三个能够创建数量的函数,那么那些DLL同时应该提供二个函数销毁那些数据。数据的创始和消除应该在同3个层次上。 V.
      DLL的磨难 人们将不相同版本DLL混合造成的不相同性形象的称为
      “动态连接库的火坑“(DLL Hell)
      ,甚至微软团结也那样说(http://msdn.microsoft.com/library/techart/dlldanger1.htm)。
      如果您的主次选择你本人的DLL时请留意:
      1.无法将debug和release版的DLL混合在一起利用。debug都是debug版,release版都以release版。
      消除办法是将debug和release的程序分别位于主程序的debug和release目录下
      2.千万并非认为静态连接库会消除难点,那只会使事态更不好。 VI.
      RELEASE板中的调节和测试 : 1.将ASSE安德拉T() 改为 VERAV4IFY()
      。找出概念在”#ifdef
      _DEBUG”中的代码,假若在RELEASE版本中需求那一个代码请将他们移到定义外。查找TRACE(…)中代码,因为那么些代码在RELEASE中也不被编写翻译。
      请认真检查那个在RELEASE中须要的代码是或不是并不曾被便宜。
      2.变量的初叶化所拉动的不比,在不一致的体系,或是在DEBUG/RELEASE版本间都存在这么的区别,所以请对变量举行开始化。
      3.是还是不是在编译时曾经有了警示?请将警告级别设置为3或4,然后保险在编写翻译时没有警示现身. VII.
      将Project Settings” 中 “C++/C ”
      项目下优化增选改为Disbale(Debug)。编写翻译器的优化可能导致不可计数意想不到的荒谬,请参见http://www.pgh.net/~newcomer/debug\_release.htm
      1.其它对RELEASE版本的软件也足以实行调节和测试,请做如下改变:
      在”Project Settings” 中 “C++/C ” 项目下设置 “category” 为
      “General” 并且将”Debug Info”设置为 “Program Database”。
      在”Link”项目下选中”Generate Debug Info”检查框。 “Rebuild All”
      如此做法会产生的有个别限量: 不恐怕取得在MFC DLL中的变量的值。
      必须对该软件研商所利用的具有DLL工程都实行更改。 另: MS
      BUG:MS的一份技术文书档案中标明,在VC5中对此DLL的”马克西姆ize
      Speed”优化增选并未被统统协理,因而那将会引起内存错误并招致程序崩溃

相关文章