Debug vs Release

原文:http://blogs.msdn.com/xiangfan/archive/2008/08/30/debug-vs-release.aspx

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

这里是常见的看法:http://forums.msdn.microsoft.com/en-US/vcgeneral/thread/775ce067-b225-4141-8b86-2d7e9b61db97/

syperk说:"As a result, I've switched to compiling my debug builds using the /MD switch. If you do this, you also have to undefine the _DEBUG preprocessor macro. Otherwise you get lots of errors about _CrtDebugReportW() not found. This function is apparently inserted into your code if _DEBUG is defined, but is only defined in the debug CRT. As long as optimization is off it seems to be perfectly possible to debug programs compiled this way, and there are no concerns about CRT incompatibility.".

但是他的说法并不完全正确。混用有很多问题。其中,最重要的一点是,混用通过不同的编译参数生成的模块是非常糟糕的做法,特别是涉及到条件编译的时候。

实际上,"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>
using namespace std;
int main()
{
    std::string str;
    return 0;
}

你会说,这个程序工作的好好的啊。如果你进一步的查看生成的exe文件,你会发现它实际上引用了两个dll,一个是msvcp90d.dll,另一个是msvcr90.dll。你混用了Debug版本和Release版本的运行时库。这同时掩盖了潜在的不兼容!

关键在这里(use_ansi.h):

#ifdef _DEBUG
#pragma comment(lib,"msvcprtd")
#else /* _DEBUG */
#pragma comment(lib,"msvcprt")
#endif /* _DEBUG */

如果你禁用了这里的自动链接,并手动链接到msvcp90.dll,你将得到“unresolved symbol”的错误。这是因为在Debug模式和Release模式下,string类的实现是不同的。这是一个很好的不兼容的例子。

error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(struct std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Has_debug_it)" (__imp_??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@U_Has_debug_it@01@@Z) referenced in function _main

幸运的是,这仅仅是一个链接时错误。否则你将不得不花费大量的时间在运行期找出这些很隐蔽的不兼容问题。

VC9中的STL实现花费了不少精力避免上述的问题。因此你可以在你的程序中禁用"_HAS_ITERATOR_DEBUGGING"宏,并同时和运行时库保持兼容(运行时库编译的时候这个宏是定义的)。但前提是你的程序必须和运行时库使用一致的Debug或者Relese模式。因此不要混用Debug和Release模式。最好是能够保证各个模块使用完全一致的编译参数进行编译。这样你就不必为潜在的不兼容问题烦恼了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值