﻿<?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++博客-alex-文章分类-Technique</title><link>http://www.cppblog.com/alexzhu/category/3459.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 21 Jul 2009 11:52:57 GMT</lastBuildDate><pubDate>Tue, 21 Jul 2009 11:52:57 GMT</pubDate><ttl>60</ttl><item><title>FSM的研究</title><link>http://www.cppblog.com/alexzhu/articles/89883.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Sun, 12 Jul 2009 10:39:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/89883.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/89883.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/89883.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/89883.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/89883.html</trackback:ping><description><![CDATA[关于FSM的实现，这两天要好好研究一下
<img src ="http://www.cppblog.com/alexzhu/aggbug/89883.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2009-07-12 18:39 <a href="http://www.cppblog.com/alexzhu/articles/89883.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Difference between select() and poll()</title><link>http://www.cppblog.com/alexzhu/articles/67491.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Fri, 21 Nov 2008 06:59:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/67491.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/67491.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/67491.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/67491.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/67491.html</trackback:ping><description><![CDATA[<h2>Whats the difference between select() and poll()? </h2>
<pre>  From Richard Stevens (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#115;&#116;&#101;&#118;&#101;&#110;&#115;&#64;&#110;&#111;&#97;&#111;&#46;&#101;&#100;&#117;"><u><font color=#0000ff>rstevens@noao.edu</font></u></a>):
The basic difference is that select()'s fd_set is a bit mask and
therefore has some fixed size.  It would be possible for the kernel to
not limit this size when the kernel is compiled, allowing the
application to define FD_SETSIZE to whatever it wants (as the comments
in the system header imply today) but it takes more work.  4.4BSD's
kernel and the Solaris library function both have this limit.  But I
see that BSD/OS 2.1 has now been coded to avoid this limit, so it's
doable, just a small matter of programming. :-)  Someone should file a
Solaris bug report on this, and see if it ever gets fixed.
With poll(), however, the user must allocate an array of pollfd
structures, and pass the number of entries in this array, so there's
no fundamental limit.  As Casper notes, fewer systems have poll() than
select, so the latter is more portable.  Also, with original
implementations (SVR3) you could not set the descriptor to -1 to tell
the kernel to ignore an entry in the pollfd structure, which made it
hard to remove entries from the array; SVR4 gets around this.
Personally, I always use select() and rarely poll(), because I port my
code to BSD environments too.  Someone could write an implementation
of poll() that uses select(), for these environments, but I've never
seen one. Both select() and poll() are being standardized by POSIX
1003.1g.
</pre>
<img src ="http://www.cppblog.com/alexzhu/aggbug/67491.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2008-11-21 14:59 <a href="http://www.cppblog.com/alexzhu/articles/67491.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unix domain sockets Versus  IP sockets</title><link>http://www.cppblog.com/alexzhu/articles/66604.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Tue, 11 Nov 2008 07:28:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/66604.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/66604.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/66604.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/66604.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/66604.html</trackback:ping><description><![CDATA[There are a few differences that might be of interest, in addition to the<br>already pointed out difference that if you start out using IP sockets, you<br>don't have to <span style="COLOR: red">migrate </span>to them later when you want inter-machine<br>connectivity: <br><br>- UNIX domain sockets use the file system as the address name space.&nbsp; This<br>&nbsp; means you can use <span style="COLOR: red">UNIX file permissions to control access to commu</span>nicate<br>&nbsp; with them.&nbsp; I.e., you can limit what other processes can connect to the<br>&nbsp; daemon -- maybe one user can, but the web server can't, or the like.<br>&nbsp; With IP sockets, the ability to connect to your daemon is exposed off<br>&nbsp; the current system, so additional steps may have to be taken for<br>&nbsp; security.&nbsp; On the other hand, you get network transparency.&nbsp; With UNIX<br>&nbsp; domain sockets, you can actually retrieve the credential of the process<br>&nbsp; that created the remote socket, and use that for access control also,<br>&nbsp; which can be quite convenient on multi-user systems.<br><br>- IP sockets over localhost are basically looped back network on-the-wire<br>&nbsp; IP.&nbsp; There is intentionally "no special knowledge" of the fact that the<br>&nbsp; connection is to the same system, so no effort is made to bypass the<br>&nbsp; normal IP stack mechanisms for performance reasons.&nbsp; For example,<br>&nbsp; transmission over TCP will always involve two context switches to get to<br>&nbsp; the remote socket, as you have to switch through the netisr, which<br>&nbsp; occurs following the "loopback" of the packet through the synthetic<br>&nbsp; loopback interface.&nbsp; Likewise, you get all the overhead of ACKs, TCP<br>&nbsp; flow control, encapsulation/decapsulation, etc.&nbsp; Routing will be<br>&nbsp; performed in order to decide if the packets go to the localhost.<br>&nbsp; Large sends will have to be broken down into MTU-size datagrams, which<br>&nbsp; also adds overhead for large writes.&nbsp; It's really TCP, it just goes over<br>&nbsp; a loopback interface by virtue of a special address, or discovering that<br>&nbsp; the address requested is served locally rather than over an ethernet<br>&nbsp; (etc). <br><br>- UNIX domain sockets have explicit knowledge that they're executing on<br>&nbsp; the same system.&nbsp; They avoid the extra context switch through the<br>&nbsp; netisr, and a sending thread will write the stream or datagrams directly<br>&nbsp; into the receiving socket buffer.&nbsp; No checksums are calculated, no<br>&nbsp; headers are inserted, no routing is performed, etc.&nbsp; Because they have<br>&nbsp; access to the remote socket buffer, they can also directly provide<br>&nbsp; feedback to the sender when it is filling, or more importantly,<br>&nbsp; emptying, rather than having the added overhead of explicit<br>&nbsp; acknowledgement and window changes.&nbsp; The one piece of functionality that<br>&nbsp; UNIX domain sockets don't provide that TCP does is out-of-band data.&nbsp; In<br>&nbsp; practice, this is an issue for almost noone.<br><br>In general, the argument for implementing over TCP is that it gives you<br>location independence and immediate portability -- you can move the client<br>or the daemon, update an address, and it will "just work".&nbsp; The sockets<br>layer provides a reasonable abstraction of communications services, so<br>it's not hard to write an application so that the connection/binding<br>portion knows about TCP and UNIX domain sockets, and all the rest just<br>uses the socket it's given.&nbsp; So if you're looking for performance locally,<br>I think UNIX domain sockets probably best meet your need.&nbsp; <span style="COLOR: red">Many people<br>will code to TCP anyway because performance is often less critical, and<br>the network portability benefit is substantial.<br></span><br>Right now, the UNIX domain socket code is covered by a subsystem lock; I<br>have a version that used more fine-grain locking, but have not yet<br>evaluated the performance impact of those changes.&nbsp; I've you're running in<br>an SMP environment with four processors, it could be that those changes<br>might positively impact performance, so if you'd like the patches, let me<br>know.&nbsp; Right now they're on my schedule to start testing, but not on the<br>path for inclusion in FreeBSD 5.4.&nbsp; The primary benefit of greater<br>granularity would be if you had many pairs of threads/processes<br>communicating across processors using UNIX domain sockets, and as a result<br>there was substantial contention on the UNIX domain socket subsystem lock. <br>The patches don't increase the cost of normal send/receive operations, but<br>due add extra mutex operations in the listen/accept/connect/bind paths.<br>
<img src ="http://www.cppblog.com/alexzhu/aggbug/66604.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2008-11-11 15:28 <a href="http://www.cppblog.com/alexzhu/articles/66604.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>a sample to explain how volatile works</title><link>http://www.cppblog.com/alexzhu/articles/29558.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Wed, 08 Aug 2007 02:48:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/29558.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/29558.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/29558.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/29558.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/29558.html</trackback:ping><description><![CDATA[<p>//the code also can be a simple sample to implement timer<font face=#ce_temp_font#><br><br><br>#include &lt;stdio.h&gt;<br>#include &lt;signal.h&gt;<br>#include &lt;sched.h&gt;<br>#include &lt;sys/time.h&gt;</font></p>
<p><font face=#ce_temp_font#>#ifndef VOLATILE<br>#define VOLATILE<br>#endif</font></p>
<p><font face=#ce_temp_font#>VOLATILE int total = 0;</font></p>
<p><font face=#ce_temp_font#>void handle(int signo)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static int count = 0;</font></p>
<p><font face=#ce_temp_font#>/*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("timer expired %d times\n", ++count); */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Total = %d\n", total);<br>}</font></p>
<p><font face=#ce_temp_font#>int main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i,x;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct itimerval val;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigaction sa;</font></p>
<p><font face=#ce_temp_font#>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(&amp;sa, 0, sizeof(sa));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sa.sa_handler = handle;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigaction(SIGVTALRM, &amp;sa, NULL);</font></p>
<p><font face=#ce_temp_font#>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val.it_interval.tv_sec = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val.it_interval.tv_usec = 10000;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val.it_value.tv_sec = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val.it_value.tv_usec = 10000;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setitimer(ITIMER_VIRTUAL, &amp;val, NULL);</font></p>
<p><font face=#ce_temp_font#>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(total &lt; 500)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i = 0; i &lt; 100; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x = x + i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</font></p>
<p><font face=#ce_temp_font#>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("X = %d\n", x);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("Total = %d\n", total);<br>}</font></p>
<p><font face=#ce_temp_font#></font>&nbsp;</p>
<img src ="http://www.cppblog.com/alexzhu/aggbug/29558.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2007-08-08 10:48 <a href="http://www.cppblog.com/alexzhu/articles/29558.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>how to implement a timer</title><link>http://www.cppblog.com/alexzhu/articles/29557.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Wed, 08 Aug 2007 02:46:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/29557.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/29557.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/29557.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/29557.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/29557.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 8pt"><font face=#ce_temp_font#>#include &lt;stdio.h&gt;<br>#include &lt;unistd.h&gt;<br>#include &lt;signal.h&gt;<br>#include &lt;stdlib.h&gt;</font></p>
<font face=#ce_temp_font#>
<p style="FONT-SIZE: 8pt"><br>timer_t mytimer;</p>
<p style="FONT-SIZE: 8pt">extern "C" void timer_intr(int sig, siginfo_t *extra, void *cruft)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf("timer_intr called\n");<br>}</p>
<p style="FONT-SIZE: 8pt">int main()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigset_t sigset;</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigfillset(&amp;sigset);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigdelset(&amp;sigset, SIGRTMIN);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigprocmask(SIG_SETMASK, &amp;sigset, NULL);</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigaction sa;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sigfillset(&amp;sa.sa_mask);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sa.sa_flags = SA_SIGINFO;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sa.sa_sigaction = timer_intr;</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(sigaction(SIGRTMIN, &amp;sa, NULL) &lt; 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("timer thread: sigaction..\n");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(-2);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct sigevent timer_event;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct itimerspec timer;</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.it_interval.tv_sec = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.it_interval.tv_nsec = 999 * 1000 * 1000;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer.it_value = timer.it_interval;</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer_event.sigev_notify = SIGEV_SIGNAL;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer_event.sigev_signo = SIGRTMIN;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timer_event.sigev_value.sival_ptr = (void *)&amp;mytimer;</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(timer_create(CLOCK_REALTIME, &amp;timer_event, &amp;mytimer) &lt; 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("timer_create");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(-1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(timer_settime(mytimer, 0, &amp;timer, NULL) &lt; 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror("timer_settime");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit(-1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(1)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pause();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p style="FONT-SIZE: 8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>}</font></p>
<img src ="http://www.cppblog.com/alexzhu/aggbug/29557.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2007-08-08 10:46 <a href="http://www.cppblog.com/alexzhu/articles/29557.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>API mt-safe and mt unsafe</title><link>http://www.cppblog.com/alexzhu/articles/19501.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Fri, 09 Mar 2007 08:13:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/19501.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/19501.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/19501.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/19501.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/19501.html</trackback:ping><description><![CDATA[
		<p>
				<font size="2">有一些api通常会有两个版本：mt-safe 和 mt unsafe. 例如：rand() 和rand_r(); token() 和token_r().<br /><br /> int rand(void);<br /></font>
				<font size="2"> int rand_r(unsigned int *seed);<br /><br /></font>
		</p>
		<p>
				<font size="2">char *strtok(char *s1, const char *s2);<br /></font>
				<font size="2">char *strtok_r(char *s1, const char *s2, char **lasts);<br /><br />后面有_r的是mt safe的。<br />为什么rand()和strtok()是mt unsafe呢？主要是函数里面有static变量，或者用到了全局变量。<br /><br />以strtok()为例：<br />下面的代码根据指定的分隔符来遍历一个字符串。<br />for(token = strtok(strSrc, delimiter); token; token = strtok(NULL, delimiter))<br />{<br /><br />}<br />每次调用strtok(), 该函数会记住下次遍历的起始位置。怎么记住？就要靠static变量，或者全局变量了。<br />这样就导致该函数是mt unsafe.<br /><br />对于strtok_r(), 每次调用的时候，需要caller定义一个指针，将其地址作为参数传给char **lasts.目的也是要记住下次遍历的起始位置。不过，这个值得存储空间是有caller来指定的。所以就是mt safe。<br /><br /><br /></font>
		</p>
<img src ="http://www.cppblog.com/alexzhu/aggbug/19501.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2007-03-09 16:13 <a href="http://www.cppblog.com/alexzhu/articles/19501.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转贴：Understand Debug Version and Release Version</title><link>http://www.cppblog.com/alexzhu/articles/19004.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Mon, 26 Feb 2007 11:38:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/19004.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/19004.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/19004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/19004.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/19004.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">看到这好文章，收藏 :-)<br /><br />经常在</span> CSDN <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上看见有人问</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">运行正常但</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">失败的问题。以往的讨论往往是经验性的，并没有指出会这样的真正原因是什么，要想找出真正的原因通常要凭运气。最近我看了一些这方面的书，又参考了</span> CSDN <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">上的一些帖子，然后深入研究了一下关于二者的不同。以下是我的一些体会，拿来与大家共享。</span> -------------------------------------- <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本文主要包含如下内容：</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">1. Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译方式的本质区别</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">2. <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">哪些情况下</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版会出错</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">3. <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">怎样</span>"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调试</span>" Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版的程序</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一、关于</span>Debug<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span>Release<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之本质区别的讨论</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译方式的本质区别</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常称为调试版本，它包含调试信息，并且不作任何优化，便于程序员调试程序。</span>Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">称为发布版本，它往往是进行了各种优化，使得程序在代码大小和运行速度上都是最优的，以便用户很好地使用。</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的真正秘密，在于一组编译选项。</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面列出了分别针对二者的选项（当然除此之外还有其他一些，如</span>/Fd /Fo<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，但区别并不重要，通常他们也不会引起</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版错误，在此不讨论）</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本：</span> /MDd /MLd <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span> /MTd <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用</span> Debug runtime library(<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调试版本的运行时刻函数库</span>) /Od <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关闭优化开关</span> /D "_DEBUG" <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相当于</span> #define _DEBUG,<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开编译调试代码开关</span>(<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">主要针对</span> assert<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数</span>) /ZI <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">创建</span> Edit and continue(<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编辑继续</span>)<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">数据库，这样在调试过</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程中如果修改了源代码不需重新编译</span> /GZ <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以帮助捕获内存错误</span> /Gm <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打开最小化重链接开关，减少链接时间</span>.</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本：</span> /MD /ML <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span> /MT <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">使用发布版本的运行时刻函数库</span> /O1 <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span> /O2 <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">优化开关，使程序最小或最快</span> /D "NDEBUG" <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关闭条件编译调试代码开关</span>(<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">即不编译</span>assert<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数</span>) /GF <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">合并重复的字符串，并将字符串常量放到只读内存，防止</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">被修改</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实际上，</span>Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并没有本质的界限，他们只是一组编译选项的集合，编译器只是按照预定的选项行动。事实上，我们甚至可以修改这些选项，从而得到优化过的调试版本或是带跟踪语句的发布版本。</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span style="mso-spacerun: yes"> </span>
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">二、哪些情况下</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版会出错</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有了上面的介绍，我们再来逐个对照这些选项看看</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版错误是怎样产生的</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">1. Runtime Library<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">链接哪种运行时刻函数库通常只对程序的性能产生影响。调试版本的</span> Runtime Library <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">包含了调试信息，并采用了一些保护机制以帮助发现错误，因此性能不如发布版本。编译器提供的</span> Runtime Library <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常很稳定，不会造成</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版错误；倒是由于</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> Runtime Library <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">加强了对错误的检测，如堆内存分配，有时会出现</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有错但</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">正常的现象。应当指出的是，如果</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">有错，即使</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">正常，程序肯定是有</span> Bug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的，只不过可能是</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版的某次运行没有表现出来而已。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">2. <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">优化：这是造成错误的主要原因，因为关闭优化时源程序基本上是直接翻译的，而打开优化后编译器会作出一系列假设。这类错误主要有以下几种：</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">(1) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">帧指针</span>(Frame Pointer)<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">省略（简称</span> FPO <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）：在函数调用过程中，所有调用信息（返回地址、参数）以及自动变量都是放在栈中的。若函数的声明与实现不同（参数、返回值、调用方式），就会产生错误————但</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方式下，栈的访问通过</span> EBP <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">寄存器保存的地址实现，如果没有发生数组越界之类的错误（或是越界</span>"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不多</span>"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），函数通常能正常执行；</span>Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">方式下，优化会省略</span> EBP <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">栈基址指针，这样通过一个全局指针访问栈就会造成返回地址错误是程序崩溃。</span>C++ <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的强类型特性能检查出大多数这样的错误，但如果用了强制类型转换，就不行了。你可以在</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本中强制加入</span> /Oy- <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">编译选项来关掉帧指针省略，以确定是否此类错误。此类错误通常有：</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span style="mso-spacerun: yes"> </span>
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">●</span> MFC <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">消息响应函数书写错误。</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">正确的应为</span> afx_msg LRESULT OnMessageOwn(WPARAM wparam, LPARAM lparam); ON_MESSAGE <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏包含强制类型转换。防止这种错误的方法之一是重定义</span> ON_MESSAGE <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏，把下列代码加到</span> stdafx.h <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中（在</span>#include "afxwin.h"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之后）</span>,<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数原形错误时编译会报错</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">#undef ON_MESSAGE </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">#define ON_MESSAGE(message, memberFxn) \ { message, 0, 0, 0, AfxSig_lwl, \ (AFX_PMSG)(AFX_PMSGW)(static_cast&lt; LRESULT (AFX_MSG_CALL \ CWnd::*)(WPARAM, LPARAM) &gt; (&amp;memberFxn) }, </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">(2) volatile <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">型变量：</span>volatile <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">告诉编译器该变量可能被程序之外的未知方式修改（如系统、其他进程和线程）。优化程序为了使程序性能提高，常把一些变量放在寄存器中（类似于</span> register <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关键字），而其他进程只能对该变量所在的内存进行修改，而寄存器中的值没变。如果你的程序是多线程的，或者你发现某个变量的值与预期的不符而你确信已正确的设置了，则很可能遇到这样的问题。这种错误有时会表现为程序在最快优化出错而最小优化正常。把你认为可疑的变量加上</span> volatile <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">试试。</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">(3) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">变量优化：优化程序会根据变量的使用情况优化变量。例如，函数中有一个未被使用的变量，在</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版中它有可能掩盖一个数组越界，而在</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版中，这个变量很可能被优化调，此时数组越界会破坏栈中有用的数据。当然，实际的情况会比这复杂得多。与此有关的错误有：</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span style="mso-spacerun: yes"> </span>
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">●</span>
						<span lang="ZH-CN">
						</span>
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">非法访问，包括数组越界、指针错误等。</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">例如</span>
						<span lang="ZH-CN">
						</span>
				</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">void fn(void) </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">{ </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">int i; </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">i = 1; </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">int a[4]; </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">{ </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">int j; </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">j = 1; </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">} </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">a[-1] = 1;//<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当然错误不会这么明显，例如下标是变量</span> a[4] = 1; </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">} </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">j <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">虽然在数组越界时已出了作用域，但其空间并未收回，因而</span> i <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span> j <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就会掩盖越界。而</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版由于</span> i<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</span>j <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并未其很大作用可能会被优化掉，从而使栈被破坏。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">3. _DEBUG <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</span> NDEBUG <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：当定义了</span> _DEBUG <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时，</span>assert() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数会被编译，而</span> NDEBUG <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">时不被编译。除此之外，</span>VC++<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中还有一系列断言宏。这包括：</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">ANSI C <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">断言</span> void assert(int expression ); </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">C Runtime Lib <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">断言</span> _ASSERT( booleanExpression ); _ASSERTE( booleanExpression ); </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">MFC <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">断言</span> ASSERT( booleanExpression ); </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">VERIFY( booleanExpression ); </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">ASSERT_VALID( pObject ); </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">ASSERT_KINDOF( classname, pobject ); ATL <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">断言</span> ATLASSERT( booleanExpression ); </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">此外，</span>TRACE() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏的编译也受</span> _DEBUG <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">控制。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所有这些断言都只在</span> Debug<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版中才被编译，而在</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版中被忽略。唯一的例外是</span> VERIFY() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。事实上，这些宏都是调用了</span> assert() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数，只不过附加了一些与库有关的调试代码。如果你在这些宏中加入了任何程序代码，而不只是布尔表达式（例如赋值、能改变变量值的函数调用</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等），那么</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版都不会执行这些操作，从而造成错误。初学者很容易犯这类错误，查找的方法也很简单，因为这些宏都已在上面列出，只要利用</span> VC++ <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span> Find in Files <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能在工程所有文件中找到用这些宏的地方再一一检查即可。另外，有些高手可能还会加入</span> #ifdef _DEBUG <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之类的条件编译，也要注意一下。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">顺便值得一提的是</span> VERIFY() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏，这个宏允许你将程序代码放在布尔表达式里。这个宏通常用来检查</span> Windows API <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的返回值。有些人可能为这个原因而滥用</span><span lang="ZH-CN"></span>VERIFY() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，事实上这是危险的，因为</span> VERIFY() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">违反了断言的思想，不能使程序代码和调试代码完全分离，最终可能会带来很多麻烦。因此，专家们建议尽量少用这个宏。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">4. /GZ <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选项：这个选项会做以下这些事</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">(1) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化内存和变量。包括用</span> 0xCC <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化所有自动变量，</span>0xCD ( Cleared Data ) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化堆中分配的内存（即动态分配的内存，例如</span> new <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），</span>0xDD ( Dead Data ) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">填充已被释放的堆内存（例如</span> delete <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">），</span>0xFD( deFencde Data ) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化受保护的内存（</span>debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版在动态分配内存的前后加入保护内存以防止越界访问），其中括号中的词是微软建议的助记词。这样做的好处是这些值都很大，作为指针是不可能的（而且</span> 32 <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">位系统中指针很少是奇数值，在有些系统中奇数的指针会产生运行时错误），作为数值也很少遇到，而且这些值也很容易辨认，因此这很有利于在</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版中发现</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版才会遇到的错误。要特别注意的是，很多人认为编译器会用</span> 0 <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来初始化变量，这是错误的（而且这样很不利于查找错误）。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">(2) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过函数指针调用函数时，会通过检查栈指针验证函数调用的匹配性。（防止原形不匹配）</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; TEXT-INDENT: 0.5in; LINE-HEIGHT: 14pt">
				<font size="2">(3) <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数返回前检查栈指针，确认未被修改。（防止越界访问和原形不匹配，与第二项合在一起可大致模拟帧指针省略</span> FPO <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常</span> /GZ <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选项会造成</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版出错而</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版正常的现象，因为</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版中未初始化的变量是随机的，这有可能使指针指向一个有效地址而掩盖了非法访问。</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">除此之外，</span>/Gm /GF <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">等选项造成错误的情况比较少，而且他们的效果显而易见，比较容易发现。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">三、怎样</span>"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调试</span>" Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版的程序</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">遇到</span> Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">成功但</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">失败，显然是一件很沮丧的事，而且往往无从下手。如果你看了以上的分析，结合错误的具体表现，很快找出了错误，固然很好。但如果一时找不出，以下给出了一些在这种情况下的策略。</span> 1. <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">前面已经提过，</span>Debug <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">只是一组编译选项的差别，实际上并没有什么定义能区分二者。我们可以修改</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版的编译选项来缩小错误范围。如上所述，可以把</span> Release <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的选项逐个</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">注：那篇文章到此就完了，好像还有一些没了。</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">
						<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>VC<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中当整个工程较大时，软件时常为出现在</span>DEBUG<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态下能运行而在</span>RELEASE<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态下无法运行的情况。由于开发者通常在</span>DEBUG<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">状态下开发软件，所以这种情况时常是在我们辛苦工作一两个月后，满怀信心的准备将软件发行时发生。为了避免无谓的损失，我们最好进行以下的检查</span>: </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">1<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、时常测试软件的两种版本。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">2<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、不要轻易将问题归结为</span>DEBUG/RELEASE<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">问题，除非你已经充分对两种版本进行了测试。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">3<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、预处理的不同，也有可能引起这样的问题。出现问题的一种可能性是在不同版本的编译间定义了不同的预处理标记。请对你的</span>DEBUG<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本的软件试一下以下改动：</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>"Project Setting(ALT-F7)" <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的</span>C/C++<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项中设置目录</span>(category)<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为</span>"General"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">，并且改动</span>"_DEBUG"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定义为</span>"NDEBUG". <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置目录为</span>"Preprocessor"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并且添加定义</span>"_DEBUG<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到</span>"Undefined Symbols"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">输入框</span>. <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">选择</span>Rebuild ALL,<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">重新编译</span>. <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如果经过编译的程序产生了问题，请对代码进行如下改动：</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">将</span>ASSERT() <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">改为</span> VERIFY(). <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">找出定义在</span>"#ifdef _DEBUG"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的代码，如果在</span>RELEASE<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本中需要这些代码请将他们移到定义外。</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">查找</span>TRACE(...)<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中代码，因为这些代码在</span>RELEASE<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中也不被编译。</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">所以请认真检查那些在</span>RELEASE<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中需要的代码是否并没有被便宜。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">4<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、变量的初始化所带来的不同，在不同的系统，或是在</span>DEBUG/RELEASE<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本间都存在这样的差异，所以请对变量进行初始化。</span><span lang="ZH-CN"></span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">5<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、是否在编译时已经有了警告</span>?<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">请将警告级别设置为</span>3<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">或</span>4,<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">然后保证在编译时没有警告出现</span>.</font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">6<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、是否改动了资源文件</span>. </font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<font size="2">7<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、此外对</span>RELEASE<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">版本的软件也可以进行调试，请做如下改动：</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>"Project Settings" <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中</span> "C++/C " <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目下设置</span> "category" <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为</span> "General" <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">并且将</span>"Debug Info"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">设置为</span> "Program Database". <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>"Link"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">项目下选中</span>"Generate Debug Info"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">检查框。</span> "Rebuild All" <span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如此做法会产生的一些限制：</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">无法获得在</span>MFC DLL<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的变量的值。</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须对该软件所使用的所有</span>DLL<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">工程都进行改动。</span><span lang="ZH-CN"></span><span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">另：</span> MS BUG<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">：</span>MS<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的一份技术文档中表明，在</span>VC5<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中对于</span>DLL<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span>"Maximize Speed"<span lang="ZH-CN" style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">优化选项并未被完全支持，因此这将会引起内存错误并导致程序崩溃。</span></font>
		</p>
		<p class="MsoNormal" style="MARGIN: 0in 0in 0pt; LINE-HEIGHT: 14pt">
				<o:p>
						<font size="2"> </font>
				</o:p>
		</p>
<img src ="http://www.cppblog.com/alexzhu/aggbug/19004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2007-02-26 19:38 <a href="http://www.cppblog.com/alexzhu/articles/19004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>different between C and C++ when initialize the structure</title><link>http://www.cppblog.com/alexzhu/articles/18172.html</link><dc:creator>alex</dc:creator><author>alex</author><pubDate>Tue, 30 Jan 2007 02:39:00 GMT</pubDate><guid>http://www.cppblog.com/alexzhu/articles/18172.html</guid><wfw:comment>http://www.cppblog.com/alexzhu/comments/18172.html</wfw:comment><comments>http://www.cppblog.com/alexzhu/articles/18172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/alexzhu/comments/commentRss/18172.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/alexzhu/services/trackbacks/18172.html</trackback:ping><description><![CDATA[when initialize a sturcture, its different between c and c++.<br />for example:<br />struct Student<br />{<br />      int id;<br />      int age;<br />      char *name;<br />};<br /><br />const int def_id = 999;<br />const int def_age = 18;<br /><br />struct Student stud = <br />   {<br />         def_id,<br />         def_age,<br />         "jackson"<br />   };<br /><br />the code can not be compiled in c but can be compiled in c++.<br /><br />Reason:<br />   In c, only constant value can be used to initialize a structure.<br />   but in c, only Micor and Enum is constant value.  const just means the value of the variable can not be changed , but the variable is not constant.<img src ="http://www.cppblog.com/alexzhu/aggbug/18172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/alexzhu/" target="_blank">alex</a> 2007-01-30 10:39 <a href="http://www.cppblog.com/alexzhu/articles/18172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>