关于bin和obj文件夹。debug 和release的区别

简介: bin是放最终代码的目录   obj就放中间代码的目录       release和debug是不同的运行方式   debug会增加调试代码,方便调试。调试完后,用release版本发布,没有调试代码,减小程序体积,加快执行速度!Top   既然obj就放中间代码的目录,为什吗还要release呢?同理,既然bin是放最终代码的目录还要debug干什吗?不是多此一举吗?Top   哎!   一、先说说   编译:       编译一个源程序文件,要经过 语法、类型,甚至要判断执行时的可行性等。

bin是放最终代码的目录   
obj就放中间代码的目录   
    
release和debug是不同的运行方式   
debug会增加调试代码,方便调试。调试完后,用release版本发布,没有调试代码,减小程序体积,加快执行速度!Top

 

既然obj就放中间代码的目录,为什吗还要release呢?同理,既然bin是放最终代码的目录还要debug干什吗?不是多此一举吗?Top

 

哎!   
一、先说说   编译:   
    编译一个源程序文件,要经过 
语法、类型,甚至要判断执行时的可行性等。   
    是一个对文件多次扫描的过程,最后还有代码优化的过程。会有一大堆的中间文件产生。vc6下的一个mfc项目   obj目录里会有好几M的中间(临时)文件。   
再复杂点,一个project有图片(声音)等资源文件,要调用其他DLL类库(可能是.net组件,可能是com),还可能由多个.cs文件组成。要把 这么多东西连接在一起。以前在DOS下用C或PASCAL,要先编译成.obj文件,再用link.exe连接在一起,才是一个exe文件。(记得 pascal还是fortran要用两个编译程序才能得到一个.obj的中间文件)   
    结论:编译需要大量的中间文件存放临时结果,为下一步做准备。C#是面向对象的复杂度更高!obj目录就是用来存放临时文件的!   
    
二、debug   &   release   
debug调试,你在程序中设置了断点,为什么vs.net知道在那里要停下来,当你把鼠标移到某个变量上,vs.net就会显示它当时的值?   
    因为编译器在代码中添加了许多调试需要的代码,可以让vs.net得到,返回给你。   
    这些代码当然是要占用空间和时间的,在你的程序调试完了后,可以正确运行了。完全可以去掉这些代码,这时候就应该用Release模式了。   
    
不管Debug还是Release模式,都要编译,都有中间临时代码产生,所以obj目录下有debug   release目录。两种模式编译的结果,就放在bin目录下。   
编译完后,中间临时代码是没什么用的了,所以一般不管obj目录里的东西!   
    
各位说说,我是不是可以去写书了?   :)

在用VC编译是,有debug和release两种   
    
有什么区别呢 
一个为调试版本,其中包括了出错时能够定位源代码的在行,如果源文件已经改变,定位出来会有偏移,而且,在这个版本中编译器不会进行代码优化,并且在程序中能用宏定义_DEBUG来确定当前的版本。另一个为正试版本,程序出错只是进行简单的错误处理,编译器会优化代码,以提高性能。
Release代码更小,执行更快,编译更严格,更慢   
当然就没有了调试信息


经常你会遇到DEBUG成功的版本RELEASE   就有问题,以下是问题的分析总结
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中却不行,因为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。   
    
II.             ASSERT和VERIFY   
    
1.                   ASSERT在Release版本中是不会被编译的。   
    
ASSERT宏是这样定义的   
    
                  #ifdef   _DEBUG   
                  #define   ASSERT(x)   if(   (x)   ==   0)   report_assert_failure()   
                  #else   
                  #define   ASSERT(x)   
                  #endif   
                  实际上复杂一些,但无关紧要。假如你在这些语句中加了程序中必须要有的代码   
比如   
    
ASSERT(pNewObj   =   new   CMyClass);   
    
pNewObj->MyFunction();   
    
这种时候Release版本中的pNewObj不会分配到空间   
    
所以执行到下一个语句的时候程序会报该程序执行了非法操作的错误。这时可以用VERIFY   :   
    
                  #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同时应该提供一个函数销毁这些数据。数据的创建和清除应该在同一个层次上。   
    
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.                   将ASSERT()   改为   VERIFY()   。找出定义在"#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的"Maximize   Speed"优化选项并未被完全支持,因此这将会引起内存错误并导致程序崩溃。   
    
2.                   
www.sysinternals.com有一个程序DebugView,用来捕捉OutputDebugString的输出,运行起来后(估计是自设为system   debugger)就可以观看所有程序的OutputDebugString的输出。此后,你可以脱离VC来运行你的程序并观看调试信息。     
    
3.                   有一个叫Gimpel   Lint的静态代码检查工具,据说比较好用。
http://www.gimpel.com   不过要化$的。   
    
参考文献:   
    
1)                   
http://www.cygnus-software.com/papers/release_debugging.html   
    
2)                 
http://www.pgh.net/~newcomer/debug_release.htm   

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fly_bird2008/archive/2007/09/24/1798708.aspx

相关文章
|
SQL 安全 网络协议
网络安全产品之认识漏洞扫描设备
为了保障系统的安全性,需要及时发现和修复漏洞。这可以通过漏洞扫描设备等工具进行自动化检测和修复,同时也可以加强安全意识和培训,提高人员的安全防范能力。虽然无法完全避免漏洞的存在,但通过采取有效的措施可以大大减少漏洞的数量和危害程度,保障系统的安全性和稳定性。本文让我们一起来认识漏洞扫描设备。
370 0
|
存储 自然语言处理 固态存储
ublk:来自Linux社区的新热点,基于io_uring的全新高性能用户态块设备
如果您想快速了解ublk的意义、作用及性能,请直接看第二节Q&A部分。一、简介用户态块设备,就是提供/dev/ublkbX这样的标准块设备给业务,业务读写这个块的实际IO处理由您编写的用户态的代码决定。这就好比您使用FUSE,所有对挂载于FUSE的目录的读写都是您编写的IO handler来处理一样。使用用户态块设备,您可以方便地向上层业务以块设备/dev/ublkbX的形式提供您的自定义
|
10月前
|
监控 网络协议 网络性能优化
不再困惑!一文搞懂TCP与UDP的所有区别
本文介绍网络基础中TCP与UDP的区别及其应用场景。TCP是面向连接、可靠传输的协议,适用于HTTP、FTP等需要保证数据完整性的场景;UDP是无连接、不可靠但速度快的协议,适合DNS、RIP等对实时性要求高的应用。文章通过对比两者在连接方式、可靠性、速度、流量控制和数据包大小等方面的差异,帮助读者理解其各自特点与适用场景。
|
数据采集 Web App开发 JavaScript
利用Selenium和XPath抓取JavaScript动态加载内容的实践案例
利用Selenium和XPath抓取JavaScript动态加载内容的实践案例
|
应用服务中间件 Linux 网络安全
2022年超详细在CentOS 7上安装Nginx方法(源码安装)
这篇文章提供了在CentOS 7系统上通过源码安装Nginx的详细步骤,包括从官网下载Nginx源码包、上传至虚拟机、解压、删除压缩包、编译安装前的配置、安装PCRE库(因为Nginx使用PCRE库解析正则表达式)、安装zlib和OpenSSL库(用于支持HTTPS协议)、重新编译Nginx、安装后启动Nginx服务、关闭服务、修改默认端口、以及重启服务测试等步骤。文章还提供了相关命令和操作截图,帮助用户更好地理解和执行安装过程。
2022年超详细在CentOS 7上安装Nginx方法(源码安装)
|
人工智能 运维 监控
现代化运维管理:挑战与应对策略
随着信息技术的不断发展,现代化运维管理面临着诸多挑战。本文从运维自动化、安全防护和资源优化等方面探讨了这些挑战,并提出了相应的应对策略,旨在帮助企业有效应对运维管理中的各种问题,提升系统的稳定性和可靠性。
423 1
|
7月前
|
机器学习/深度学习 人工智能 搜索推荐
AI训练师入行指南(五):模型评估
本文从珠宝鉴定类比出发,探讨AI模型从训练到优化的全流程。首先介绍模型评估的四大核心指标:准确率、精确率与召回率、F1-Score及AUC-ROC,帮助明确模型性能。接着分析阈值调节、正则化与集成学习等调优方法的实际应用,如支付宝动态人脸识别和腾讯金融风控系统。此外,针对GPT-4o、Stable Diffusion和滴滴ETA模型的具体案例,展示参数微调与审美争议解决策略。最后提供避坑指南,强调数据泄漏、过拟合和冷启动问题的应对之道,总结模型评估应以商业价值、伦理规范和用户体验为导向,确保AI模型真正成为“智能珍宝”。
325 0
|
9月前
|
存储 运维 安全
盘古分布式存储系统的稳定性实践
本文介绍了阿里云飞天盘古分布式存储系统的稳定性实践。盘古作为阿里云的核心组件,支撑了阿里巴巴集团的众多业务,确保数据高可靠性、系统高可用性和安全生产运维是其关键目标。文章详细探讨了数据不丢不错、系统高可用性的实现方法,以及通过故障演练、自动化发布和健康检查等手段保障生产安全。总结指出,稳定性是一项系统工程,需要持续迭代演进,盘古经过十年以上的线上锤炼,积累了丰富的实践经验。
690 7
|
消息中间件 Java Kafka
|
人工智能 JSON API
一张图读懂大模型应用是如何工作的,一图胜千言
用一张图,带你轻松读懂大模型应用的工作原理。不需要复杂的代码和艰深的理论,只需要一张图,就能让你对大模型有一个全新的认识
一张图读懂大模型应用是如何工作的,一图胜千言