﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-乱八七糟的代码-随笔分类-Windows ~</title><link>http://www.cppblog.com/zqsand/category/12849.html</link><description>啥是子标题</description><language>zh-cn</language><lastBuildDate>Wed, 20 Jan 2010 11:25:06 GMT</lastBuildDate><pubDate>Wed, 20 Jan 2010 11:25:06 GMT</pubDate><ttl>60</ttl><item><title>断言的使用</title><link>http://www.cppblog.com/zqsand/archive/2010/01/17/105886.html</link><dc:creator>rikisand</dc:creator><author>rikisand</author><pubDate>Sun, 17 Jan 2010 11:36:00 GMT</pubDate><guid>http://www.cppblog.com/zqsand/archive/2010/01/17/105886.html</guid><wfw:comment>http://www.cppblog.com/zqsand/comments/105886.html</wfw:comment><comments>http://www.cppblog.com/zqsand/archive/2010/01/17/105886.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zqsand/comments/commentRss/105886.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zqsand/services/trackbacks/105886.html</trackback:ping><description><![CDATA[
<p>解决项目的问题，意识到断言的重要性。如果一个程序在某处遇到了非法的值，那么最好的情况便是在此刻停下报错，最坏的情况便是程序不吭不响的执行着~~直到你发现他执行的方式极为诡异，此时，你要花九牛二虎之力才能找到错误所在之处~~~~</p> <p>学习一下断言吧：</p> <p><font size="3"><font face="YaHei Consolas Hybrid" color="#008000">&#183;&#183;&#183;&#183;&#183;&#183;&#183;什么是断言</font></font></p> <p><font face="YaHei Consolas Hybrid" color="#008000" size="3">在某处判断某一个表达式的值为真或者假，如果假则输出错误消息并停止程序的执行~</font></p> <p><font face="YaHei Consolas Hybrid" color="#008000" size="3">assert是宏，而不是函数，只在debug版本中有效，因此无需在release版本删除。</font></p> <p><font face="YaHei Consolas Hybrid" color="#008000" size="3">&#183;&#183;&#183;&#183;&#183;&#183;&#183;哪几种断言</font></p> <p><font face="YaHei Consolas Hybrid" color="#008000" size="3">MFC </font></p> <p><font face="YaHei Consolas Hybrid" color="#008000" size="3">ASSERT</font></p> <p>void foo(char* p,int size)<br>{<br>ASSERT(p != 0); // 验证缓冲区指针<br>ASSERT((size &gt;= 100); // 确认缓冲区大小至少为100字节<br>// foo 函数的其它计算过程<br>}<br>如果没有定义_DEBUG预处理符，则该语句不会真正生成代码。Visual C++会在调试模式编译时自动定义_DEBUG，而在发行模式下，该预处理符是不存在的。如果定义了_DEBUG，则上述两个断言生成的代码类如： <br>//ASSERT(p != 0);<br>do<br>{<br>if(!(p != 0) &amp;&amp; AfxAssertFailedLine(__FILE__, __LINE__))<br>AfxDebugBreak();<br>} while(0);<br>//ASSERT((size &gt;= 100);<br>do<br>{<br>if(!(size &gt;= 100) &amp;&amp; AfxAssertFailedLine(__FILE__,__LINE__))<br>AfxDebugBreak();<br>}while(0);  </p><p><font face="YaHei Consolas Hybrid" color="#008080" size="3">ASSERT_KINDOF(classname,pObject); ASSERT_KINDOF(CDocument,pDocument);</font></p> <p><font face="YaHei Consolas Hybrid" color="#008080" size="3">检验pObject指向的对象是classname类的一个对象或者其派生类的对象</font></p> <p><font face="YaHei Consolas Hybrid" color="#008080" size="3">ASSERT_VALID(pObject); pObject 必须是一个派生于CObject类的类对象，会调用其重写的AssertValid函数 ，例如</font></p> <p>如果使用应用向导或类向导生成基于MFC的类，通常会得到AssertValid()的骨架，最好改写这些骨架代码以增加最基本的完整性检查。下面是一个典型的例子，类Sample从CObject继承，假定它含有职员名字及其薪水： <br>class Sample : public CObject<br>{<br>&nbsp;&nbsp;&nbsp; protected:<br>&nbsp;&nbsp;&nbsp; CString m_Name; // 职员名字<br>&nbsp;&nbsp;&nbsp; double m_Salary; // 薪水<br>public:<br>&nbsp;&nbsp;&nbsp; Sample(LPCTSTR name,double salary) : m_Name(name), m_Salary(salary) {}<br><em>&nbsp;&nbsp; #ifdef _DEBUG<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; virtual void AssertValid() const;<br>&nbsp;&nbsp;&nbsp; #endif</em><br>};<br><em>#ifdef _DEBUG<br>void Sample::AssertValid() const<br>{<br>&nbsp;&nbsp;&nbsp; CObject::AssertValid(); // 验证基类<br>&nbsp;&nbsp;&nbsp; ASSERT(!m_Name.IsEmpty()); // 验证职员名字<br>&nbsp;&nbsp;&nbsp; ASSERT(m_Salary &gt; 0); // 验证薪水<br>}<br>#endif</em>  </p><p><font face="YaHei Consolas Hybrid" color="#408080" size="3">CRT assertion</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">_ASSERT 和&nbsp; _ASSERTE 后一个会在出错时同时打印出条件判断句</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">ANSI</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">assert()</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">注意：assert用于检测非法的输入，但是合法的输入并不一定是正确的，例如：</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">int pB = (int*)malloc(sizeof(int)*1000);</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">assert(pB!=NULL) //错误的使用assert 他会在release版本失效~也就是说assert不应该对程序产生副作用</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">正确的做法：</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">int pB = (int*) malloc(sizeof(int)*1000);</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">if(pB == NULL)</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">{<br>&nbsp;&nbsp; //错误处理</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">}</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">else{</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">}</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">另一个例子：</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">void draw(){</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">&nbsp;&nbsp; CFigure* pF = getCF();</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">&nbsp;&nbsp; assert(pf!=NULL);</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">&nbsp;&nbsp; if(pf == NULL){}</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">&nbsp;&nbsp; else{</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">&nbsp;&nbsp; }</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">}</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">此处，对于getCF来说返回值为NULL是非法的，如果他的返回值可能为null就没必要加上assert语句。</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">而下面的if语句则是为了防止release版本出现null指针的情况。 </font></p> <p><font face="YaHei Consolas Hybrid" size="3"></font><font color="#408080">&nbsp;</font></p> <p><font face="YaHei Consolas Hybrid" size="3"></font><font color="#408080">&nbsp;</font></p> <p><font face="YaHei Consolas Hybrid" color="#408080" size="3">VERIFY()</font></p> <p><font color="#408080">由于ASSERT仅在程序的调试版起作用，测试表达式总是被动的。也就是说，它们不能包含赋值、增量、减量等真正改变数据的操作。但有时候我们需要验证一个主动表达式，比如赋值语句。这时可以使用VERIFY代替ASSERT。下面是一个例子： <br>void foo(char* p,int size)<br>{<br>char* q; // 指针的副本<br><em>VERIFY(q = p);</em> // 拷贝指针并执行验证<br>ASSERT((size &gt;= 100); // 确保缓冲区大小至少为100字节<br>// 执行 foo 的其它操作<br>}<br>在调试模式下ASSERT和VERIFY是相同的。但在release模式下，VERIFY能够继续对表达式求值（但不再进行断言检验），而ASSERT语句在效果上就如同已经删除了一样。 <br>尽管在MFC源代码中可以找到一些应用VERIFY的例子，但ASSERT用得更为普遍。一些程序员总是完全避免使用VERIFY，因为他们已经习惯于使用被动断言。请记住，如果在ASSERT语句中使用了主动表达式，编译器不会发出任何警告。在发行模式下编译时该表达式会被直接删除，从而导致程序运行的错误。由于发行版程序不含调试信息，这种类型的错误是很难找到原因的。 </font> </p><p><font face="YaHei Consolas Hybrid" size="3"></font><font color="#408080">&nbsp;</font></p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font>&nbsp;</p> <p><font face="YaHei Consolas Hybrid" color="#004080" size="3"></font></p><img src ="http://www.cppblog.com/zqsand/aggbug/105886.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zqsand/" target="_blank">rikisand</a> 2010-01-17 19:36 <a href="http://www.cppblog.com/zqsand/archive/2010/01/17/105886.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>