VS中Debug模式和Release模式的区别

  • 格式:docx
  • 大小:17.34 KB
  • 文档页数:2

VS中Debug模式和Release模式的区别
有些人可能会问VC中的Debug和Release模式到底有什么区别,能不能将两者混用。

这里是常见的看法:/en-US/vcgeneral/thread/775ce067-b225-4141-8b86-2d7e9b61db97/ syperk说:"Asaresult,I'veswitchedtocompilingmydebugbuildsusingthe/MDswitch.Ifyo udothis,youalsohavetoundefinethe_DEBUGpreprocessormacro.Otherwiseyoug etlotsoferrorsabout_CrtDebugReportW()notfound.Thisfunctionisapparentl yinsertedintoyourcodeif_DEBUGisdefined,butisonlydefinedinthedebugCRT. Aslongasoptimizationisoffitseemstobeperfectlypossibletodebugprogramsc ompiledthisway,andtherearenoconcernsaboutCRTincompatibility.".
但是他的说法并不完全正确。

混用有很多问题。

其中,最重要的一点是,混用通过不同的编译参数生成的模块是非常糟糕的做法,特别是涉及到条件编译的时候。

实际上,"Debug"和"Release"只是两套IDE预先设定好的编译参数和宏定义组合(例如我们经常遇到的_DEBUG和NDEBUG宏)。

编译器并不知道Debug和Release之分(不过MD和MDd编译参数会区分Debug版本和Release版本的运行时库)。

当混用用Debug设置编译的程序和Release版本的运行时库的时候,由于它们生成的时候使用的是两套不同的编译选项,因此非常可能互不兼容。

比如,如果你在你的Debug配置中将"MDd"改为"MD"(链接到Release版本的运行时库),然后编译下面的代码(不要去掉配置中的_DEBUG宏定义,否则Debug编译模式就不再是Debug了(/MDd会隐式的定义这个宏,而IDE会显式的在配置中定义它)):
#include<iostream>
#include<string>
usingnamespacestd;
intmain()
{
std::stringstr;
return0;
}
你会说,这个程序工作的好好的啊。

如果你进一步的查看生成的exe文件,你会发现它实际上引用了两个dll,一个是msvcp90d.dll,另一个是msvcr90.dll。

你混用了Debug版本和Release版本的运行时库。

这同时掩盖了潜在的不兼容!
关键在这里(use_ansi.h):
#ifdef_DEBUG
#pragmacomment(lib,"msvcprtd")
#else/*_DEBUG*/
#pragmacomment(lib,"msvcprt")
#endif/*_DEBUG*/
如果你禁用了这里的自动链接,并手动链接到msvcp90.dll,你将得到“unresolvedsymbol”的错误。

这是因为在Debug模式和Release模式下,string 类的实现是不同的。

这是一个很好的不兼容的例子。

errorLNK2019:unresolvedexternalsymbol"__declspec(dllimport)public :__thiscallstd::basic_string<char,structstd::char_traits<char>,classs td::allocator<char>>::basic_string<char,structstd::char_traits<char>, classstd::allocator<char>>(structstd::basic_string<char,structstd::ch ar_traits<char>,classstd::allocator<char>>::_Has_debug_it)"(__imp_??0 ?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Ha s_debug_it@01@@Z)referencedinfunction_main
幸运的是,这仅仅是一个链接时错误。

否则你将不得不花费大量的时间在运行期找出这些很隐蔽的不兼容问题。

VC9中的STL实现花费了不少精力避免上述的问题。

因此你可以在你的程序中禁用"_HAS_ITERATOR_DEBUGGING"宏,并同时和运行时库保持兼容(运行时库编译的时候这个宏是定义的)。

但前提是你的程序必须和运行时库使用一致的Debug或者Relese模式。

因此不要混用Debug和Release模式。

最好是能够保证各个模块使用完全一致的编译参数进行编译。

这样你就不必为潜在的不兼容问题烦恼了。