<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Van's House : VC</title><link>http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx</link><description>Tags: VC</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Output Text in Unicode</title><link>http://blogs.msdn.com/xiangfan/archive/2009/08/04/output-text-in-unicode.aspx</link><pubDate>Tue, 04 Aug 2009 16:35:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9857123</guid><dc:creator>xiangfan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/9857123.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=9857123</wfw:commentRss><description>&lt;p&gt;According to C standard, it only supports output text in MBCS (Multi-Byte Character String):&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1124.pdf" target="_blank"&gt;n1124.pdf&lt;/a&gt;, 7.19.3/12&lt;/p&gt; &lt;p&gt;The wide character output functions convert wide characters to multibyte characters and write them to the stream as if they were written by successive calls to the fputwc function. Each conversion occurs as if by a call to the wcrtomb function, with the conversion state described by the stream’s own mbstate_t object. The byte output functions write characters to the stream as if by successive calls to the fputc function.  &lt;p&gt;However, MBCS doesn’t support mixing characters in different code page. For example, you can’t use both Chinese and Japanese.&lt;/p&gt; &lt;p&gt;VC provides extension to allow you to output text in Unicode:&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;#include&lt;/span&gt;&amp;nbsp;&lt;span style="color: rgb(163,21,21)"&gt;&amp;lt;cstdio&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;#include&lt;/span&gt;&amp;nbsp;&lt;span style="color: rgb(163,21,21)"&gt;&amp;lt;locale.h&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(163,21,21)"&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;#include&lt;/span&gt;&amp;nbsp;&lt;span style="color: rgb(163,21,21)"&gt;&amp;lt;io.h&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;#include&lt;/span&gt;&amp;nbsp;&lt;span style="color: rgb(163,21,21)"&gt;&amp;lt;fcntl.h&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(163,21,21)"&gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; OutputMBCS(FILE *f)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// ".936" is the code page for Simplified Chinese&lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// However, you can't use ".1200" (code page for Unicode) to output text in Unicode&lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; setlocale(LC_CTYPE, &lt;span style="color: rgb(163,21,21)"&gt;".936"&lt;/span&gt;);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// My name in Chinese: "范翔"&lt;/span&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fwprintf(f, L&lt;span style="color: rgb(163,21,21)"&gt;"%s"&lt;/span&gt;, L&lt;span style="color: rgb(163,21,21)"&gt;"\x8303\x7FD4"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// The text in the file is encoded in GBK&lt;/span&gt;&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0,0,255)"&gt;void&lt;/span&gt; OutputUnicode(FILE *f)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; _setmode(_fileno(f), _O_U16TEXT);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fwprintf(f, L&lt;span style="color: rgb(163,21,21)"&gt;"%s"&lt;/span&gt;, L&lt;span style="color: rgb(163,21,21)"&gt;"\x8303\x7FD4"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: rgb(0,128,0)"&gt;// The text in the file is encoded in Unicode&lt;/span&gt;&lt;br&gt;}&lt;/p&gt; &lt;p&gt;For more information, please check the following post: &lt;a href="http://blogs.msdn.com/michkap/archive/2008/03/18/8306597.aspx"&gt;http://blogs.msdn.com/michkap/archive/2008/03/18/8306597.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9857123" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category></item><item><title>Detect Shift Overflow</title><link>http://blogs.msdn.com/xiangfan/archive/2009/06/13/detect-shift-overflow.aspx</link><pubDate>Sat, 13 Jun 2009 08:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9742030</guid><dc:creator>xiangfan</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/9742030.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=9742030</wfw:commentRss><description>&lt;P&gt;This is an intellectual exercise: when shifts a 32-bit unsigned integer in C++, how to detect whether the calculation overflows efficiently?&lt;/P&gt;
&lt;P&gt;Here is the function prototype. shl_overflow will return true if v &amp;lt;&amp;lt; cl overflows (cl is between 0 and 31. And we assume that sizeof(unsigned long) == 4 and sizeof(unsigned long long) == 8).&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; shl_overflow(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt; v, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; cl)&lt;/P&gt;
&lt;P&gt;The most natural way to implement this function is to extend v to 64-bit integer:&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; shl_overflow(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt; v, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; cl)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt; vl = v;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; (vl &amp;lt;&amp;lt; cl &amp;gt;&amp;gt; 32) != 0;&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Now, let’s dig into the assembly world. We’ll limit the discussion on x86.&lt;BR&gt;&lt;BR&gt;mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, DWORD PTR _v$[esp-4]&lt;BR&gt;mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, DWORD PTR _cl$[esp-4]&lt;BR&gt;xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, edx&lt;BR&gt;call&amp;nbsp;&amp;nbsp;&amp;nbsp; __allshl&lt;BR&gt;xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;BR&gt;or&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, edx&lt;BR&gt;jne&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; overflow&lt;/P&gt;
&lt;P&gt;The implementation has to use three specific registers: eax, edx and ecx. And there is an expensive external function call.&lt;/P&gt;
&lt;P&gt;If you step into __allshl in the debugger, you can find that it will use shld to shift 64-bit integer. VC provides some intrinsics which map to CPU instructions. For example, __ll_lshift will map to shld.&lt;/P&gt;
&lt;P&gt;Because the high dword of vl is 0, we can simplify our code:&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; shl_overflow(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt; v, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; cl)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt; vl = __ll_lshift(v, cl);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; (&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static_cast&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;FONT color=#0000ff&gt;long&lt;/FONT&gt;&amp;gt;(vl &amp;gt;&amp;gt; 32)) != 0;&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;The assembly looks like:&lt;BR&gt;&lt;BR&gt;
&lt;P&gt;mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, DWORD PTR _v$[esp-4]&lt;BR&gt;mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, DWORD PTR _cl$[esp-4]&lt;BR&gt;xor&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, edx&lt;BR&gt;shld&amp;nbsp;&amp;nbsp;&amp;nbsp; edx, eax, cl&lt;BR&gt;test&amp;nbsp;&amp;nbsp;&amp;nbsp; edx&lt;BR&gt;jne&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; overflow&lt;/P&gt;
&lt;P&gt;Much better now.&lt;/P&gt;
&lt;P&gt;Another approach is based on bit representation.&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt; shl_overflow(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt; v, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; cl)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; v = _rotl(v, cl);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt; index;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; _BitScanForward(&amp;amp;index, v) ? index &amp;gt;= cl : &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;false&lt;/SPAN&gt;;&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;The idea is simple. If v &amp;lt;&amp;lt; cl overflows, that means the most significant cl bits of v should contains "1".&lt;/P&gt;
&lt;P&gt;There are two ways to test that.&lt;/P&gt;
&lt;P&gt;1. Scan v from the least significant bits to the most, and test the index against 32 – cl. However, we have to handle the case when cl = 0.&lt;/P&gt;
&lt;P&gt;2. Rotate v cl bits left first, so the most significant cl bits will be the least significant cl bits. Then we can scan and test the index against cl directly.&lt;/P&gt;
&lt;P&gt;Notice that, the scan may fail if v is 0. The second way is simpler and more efficient.&lt;/P&gt;
&lt;P&gt;The assembly looks like:&lt;/P&gt;
&lt;P&gt;mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ecx, DWORD PTR _cl$[esp-4]&lt;BR&gt;mov&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, DWORD PTR _v$[esp-4]&lt;BR&gt;rol&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, cl&lt;BR&gt;bsf&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, eax&lt;BR&gt;je&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; notoverflow&lt;BR&gt;cmp&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; eax, ecx&lt;BR&gt;jl&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; overflow&lt;/P&gt;
&lt;P&gt;It only uses two registers. It can also be extended to handle 64-bit shift. One drawback is an extra conditional jump (The extra jump can be replaced by "cmovz eax, ecx", but there is no way to ask the compiler to generate that)&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9742030" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/Optimization/default.aspx">Optimization</category></item><item><title>Recursive Algorithm in C++</title><link>http://blogs.msdn.com/xiangfan/archive/2009/05/23/recursive-algorithm-in-c.aspx</link><pubDate>Sat, 23 May 2009 17:11:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9637398</guid><dc:creator>xiangfan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/9637398.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=9637398</wfw:commentRss><description>&lt;P&gt;Many recursive algorithms have initial parameters. For example, &lt;A href="http://mathworld.wolfram.com/FibonacciNumber.html" target=_blank mce_href="http://mathworld.wolfram.com/FibonacciNumber.html"&gt;Fibonacci Number&lt;/A&gt; is defined as: Fn = Fn-1 + Fn-2, with F1 = F2 = 1.&lt;/P&gt;
&lt;P&gt;By giving different values to F1 and F2, we can generate different sequence of numbers.&lt;/P&gt;
&lt;P&gt;1. If we implement the algorithm using functions, we have to either define these parameters as global variables or pass them in each recursive iteration.&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; Fib(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; n, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f1, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f2)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n &amp;lt; 1) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; 0;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n &amp;gt;= 3) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; Fib(n - 1, f1, f2) + Fib(n - 2, f1, f2);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n == 2) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; f2;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else&lt;/SPAN&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; f1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;2. Recursive functor can store the initial parameters as the class data member. Here is the example.&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; FibFunctor&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FibFunctor(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f1, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f2) : m_f1(f1), m_f2(f2) {}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; m_f1, m_f2;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;operator&lt;/SPAN&gt;()(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; n) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;const&lt;/SPAN&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n &amp;lt; 1) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; 0;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n &amp;gt;= 3) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; (*&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;)(n - 1) + (*&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;)(n - 2);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n == 2) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; m_f2;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else&lt;/SPAN&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; m_f1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;};&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; Fib(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; n, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f1, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f2)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; FibFunctor f(f1, f2);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; f(n);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;3. &lt;A href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx" target=_blank mce_href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx"&gt;Lambda&lt;/A&gt; is a new core language feature introduced in C++0x to define implicit function object. However, "this" is not valid inside lambda expression.&lt;/P&gt;
&lt;P&gt;This post &lt;A title="Visual C++ Team Blog - Stupid Lambda Tricks" href="http://blogs.msdn.com/vcblog/archive/2008/11/18/stupid-lambda-tricks.aspx" mce_href="http://blogs.msdn.com/vcblog/archive/2008/11/18/stupid-lambda-tricks.aspx"&gt;Visual C++ Team Blog - Stupid Lambda Tricks&lt;/A&gt; shows how to write a recursive lambda. So the above functor can be rewritten as:&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; Fib(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; n, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f1, &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; f2)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;auto&lt;/SPAN&gt; f = [&amp;amp;](&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; n) -&amp;gt; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n &amp;lt; 1) &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; 0;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n &amp;gt;= 3) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; f(n - 1) + f(n - 2);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt; (n == 2) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; f2;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;else&lt;/SPAN&gt; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; f1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt; f(n);&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Here, [&amp;amp;] is equivalent to [&amp;amp;f, &amp;amp;f1, &amp;amp;f2].&lt;/P&gt;
&lt;P&gt;(According to C++03 3.3.1/1: "The point of declaration for a name is immediately after its complete declarator and before its initializer (if any).", it is legal to capture f in the lambda expression. That means:&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; A {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; A(A*);&lt;BR&gt;};&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; A a = A(&amp;amp;a); &lt;SPAN style="COLOR: rgb(0,128,0)"&gt;// OK&lt;/SPAN&gt;&lt;BR&gt;})&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9637398" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category></item><item><title>Measure Initialization Time of Global Variables</title><link>http://blogs.msdn.com/xiangfan/archive/2009/05/12/measure-initialization-time-of-global-variables.aspx</link><pubDate>Tue, 12 May 2009 15:16:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9606987</guid><dc:creator>xiangfan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/9606987.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=9606987</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;NOTICE: The technique describes in the article may not be supported in future release of VC. You should not use it in production code&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;There are two kinds of initialization in C++: static initialization and dynamic initialization.&lt;/P&gt;
&lt;P&gt;According to the standard, static initialization shall always be performed before any dynamic initialization takes place.&lt;/P&gt;
&lt;P&gt;In VC, static initialization is done at compile time. The value is stored in the data section of the generated executable. On the other hand, dynamic initialization happens at runtime. Before entering main, CRT will call the dynamic initializers of the global variables.&lt;/P&gt;
&lt;P&gt;Sometimes you may need to measure the startup time of your program. However, dynamic initialization happens before main, so your measurement will not include it.&lt;/P&gt;
&lt;P&gt;This article "&lt;A href="http://msdn.microsoft.com/en-us/library/bb918180.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/bb918180.aspx"&gt;CRT Initialization&lt;/A&gt;" describes the detailed information of how dynamic initialization works in VC. &lt;/P&gt;
&lt;P&gt;VC provides pragma &lt;A href="http://msdn.microsoft.com/en-us/library/7977wcck.aspx" target=_blank mce_href="http://msdn.microsoft.com/en-us/library/7977wcck.aspx"&gt;init_seg&lt;/A&gt; to fine-control the initialization process. It will place the dynamic initializers in the specific section. Besides predefined compiler, lib and user (the corresponding section names are ".CRT$XCC", ".CRT$XCL" and ".CRT$XCU"), you can also specify the section name explicitly.&lt;/P&gt;
&lt;P&gt;With these knowledge, we can use the following code to measure the initialization time of global variables.&lt;/P&gt;
&lt;P&gt;Let’s create two files: InitTime_Start.cpp and InitTime_End.cpp (we have to use two files because one file can only have one init_seg)&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;//InitTime_Start.cpp&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#pragma&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;warning&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;disable&lt;/SPAN&gt; : 4075)&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#pragma&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;init_seg&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;".CRT$XCB"&lt;/SPAN&gt;)&lt;BR&gt;&lt;BR&gt;Timer gInitTimer;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;//InitTime_End.cpp&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#pragma&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;warning&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;disable&lt;/SPAN&gt; : 4075)&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#pragma&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;init_seg&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;".CRT$XCY"&lt;/SPAN&gt;)&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;double&lt;/SPAN&gt; gInitTime = gInitTimer.GetTime();&lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Here, "Timer" is a class which will start timing in ctor and return the elapsed time in member function GetTime. Because ".CRT$XCB" will be placed before ".CRT$XCC", the dynamic initializer of the timer will be called before any dynamic initializers of compiler generated global variables. Similarly, gInitTimer.GetTime will be called after all the dynamic initializers of user defined global variables. Then "gInitTime" will contain the initialization time of all global variables including those generated by compiler, library and user.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9606987" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category></item><item><title>Enable syntax highlighting for TR1 headers in VS2008 SP1</title><link>http://blogs.msdn.com/xiangfan/archive/2008/12/13/enable-syntax-highlighting-for-tr1-headers-in-vs2008-sp1.aspx</link><pubDate>Sat, 13 Dec 2008 06:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9205673</guid><dc:creator>xiangfan</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/9205673.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=9205673</wfw:commentRss><description>&lt;P&gt;Unfortunately, VS2008 SP1 doesn't recognize C++ tr1 headers. That means there are no syntax highlighting and no intellisense for these files.&lt;/P&gt;
&lt;P&gt;This is a bug, but you can fix it by yourself. The trick is in the registry. VS maintains a list of extensionless files, and will treat them as cpp files.&lt;/P&gt;
&lt;P&gt;It is under: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Languages\Extensionless Files\{B2F072B0-ABC1-11D0-9D62-00C04FD9DFD9}&lt;/P&gt;
&lt;P&gt;Just add tr1 headers into it and you'll now get full support of new tr1 features. Here is the reg file:&lt;/P&gt;
&lt;P&gt;Windows Registry Editor Version 5.00 
&lt;P&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Languages\Extensionless Files\{B2F072B0-ABC1-11D0-9D62-00C04FD9DFD9}]&lt;BR&gt;"array"=""&lt;BR&gt;"random"=""&lt;BR&gt;"regex"=""&lt;BR&gt;"tuple"=""&lt;BR&gt;"type_traits"=""&lt;BR&gt;"unordered_map"=""&lt;BR&gt;"unordered_set"=""&lt;BR&gt;"xawrap"=""&lt;BR&gt;"xawrap0"=""&lt;BR&gt;"xawrap1"=""&lt;BR&gt;"xawrap2"=""&lt;BR&gt;"xfwrap"=""&lt;BR&gt;"xfwrap1"=""&lt;BR&gt;"xrefwrap"=""&lt;BR&gt;"xtr1common"=""&lt;BR&gt;"xxbind0"=""&lt;BR&gt;"xxbind1"=""&lt;BR&gt;"xxcallfun"=""&lt;BR&gt;"xxcallobj"=""&lt;BR&gt;"xxcallpmf"=""&lt;BR&gt;"xxcallwrap"=""&lt;BR&gt;"xxfunction"=""&lt;BR&gt;'xxmem_fn"=""&lt;BR&gt;"xxpmfcaller"=""&lt;BR&gt;"xxrefwrap"=""&lt;BR&gt;"xxresult"=""&lt;BR&gt;"xxtuple0"=""&lt;BR&gt;"xxtuple1"=""&lt;BR&gt;"xxtype_traits"=""&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9205673" width="1" height="1"&gt;</description><enclosure url="http://blogs.msdn.com/xiangfan/attachment/9205673.ashx" length="1222" type="application/octet-stream" /><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category></item><item><title>VC extensions list</title><link>http://blogs.msdn.com/xiangfan/archive/2008/12/11/vc-extensions-list.aspx</link><pubDate>Fri, 12 Dec 2008 01:36:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9198948</guid><dc:creator>xiangfan</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/9198948.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=9198948</wfw:commentRss><description>&lt;P&gt;MSDN has a &lt;A class="" href="http://msdn.microsoft.com/en-us/library/34h23df8(VS.80).aspx" mce_href="http://msdn.microsoft.com/en-us/library/34h23df8(VS.80).aspx"&gt;page&lt;/A&gt; describing various VC&amp;nbsp;extensions. But it is far from complete.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I've&amp;nbsp;collected&amp;nbsp;a list of nonstandard extensions&amp;nbsp;provided by VC, some of them are &lt;STRONG&gt;evil&lt;/STRONG&gt;.&amp;nbsp;If you want to&amp;nbsp;write standard conformant C++ code, you'd better be aware of these extensions which&amp;nbsp;are on by default. Some commonly (mis-)used extensions are in bold.&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/f795hcch.aspx" mce_href="http://msdn.microsoft.com/en-us/library/f795hcch.aspx"&gt;W4001&lt;/A&gt;: nonstandard extension 'single line comment' was used&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/bacb5038.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bacb5038.aspx"&gt;W4152&lt;/A&gt;: nonstandard extension, function/data pointer conversion in expression&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/79wf64bc.aspx" mce_href="http://msdn.microsoft.com/en-us/library/79wf64bc.aspx"&gt;W4200&lt;/A&gt;: nonstandard extension used : zero-sized array in struct/union&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/c89bw853.aspx" mce_href="http://msdn.microsoft.com/en-us/library/c89bw853.aspx"&gt;W4201&lt;/A&gt;: nonstandard extension used : &lt;STRONG&gt;nameless struct/union&lt;/STRONG&gt;&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/9yzc6y3b.aspx" mce_href="http://msdn.microsoft.com/en-us/library/9yzc6y3b.aspx"&gt;W4202&lt;/A&gt;: nonstandard extension used : '...': prototype parameter in name list illegal&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/yax3f30x.aspx" mce_href="http://msdn.microsoft.com/en-us/library/yax3f30x.aspx"&gt;W4203&lt;/A&gt;: nonstandard extension used : union with static member variable&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/6b73z23c.aspx" mce_href="http://msdn.microsoft.com/en-us/library/6b73z23c.aspx"&gt;W4204&lt;/A&gt;: nonstandard extension used : non-constant aggregate initializer&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/7a94ekhs.aspx" mce_href="http://msdn.microsoft.com/en-us/library/7a94ekhs.aspx"&gt;W4205&lt;/A&gt;: nonstandard extension used : static function declaration in function scope&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/2xz1ww4k.aspx" mce_href="http://msdn.microsoft.com/en-us/library/2xz1ww4k.aspx"&gt;W4206&lt;/A&gt;: nonstandard extension used : translation unit is empty&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/h40wte08.aspx" mce_href="http://msdn.microsoft.com/en-us/library/h40wte08.aspx"&gt;W4207&lt;/A&gt;: nonstandard extension used : extended initializer form&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/x9z4waxa.aspx" mce_href="http://msdn.microsoft.com/en-us/library/x9z4waxa.aspx"&gt;W4208&lt;/A&gt;: nonstandard extension used : delete [exp] - exp evaluated but ignored&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/d8fs65w0.aspx" mce_href="http://msdn.microsoft.com/en-us/library/d8fs65w0.aspx"&gt;W4210&lt;/A&gt;: nonstandard extension used : function given file scope&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/88zaxt6c.aspx" mce_href="http://msdn.microsoft.com/en-us/library/88zaxt6c.aspx"&gt;W4211&lt;/A&gt;: nonstandard extension used : redefined extern to static&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/z4cahb0t.aspx" mce_href="http://msdn.microsoft.com/en-us/library/z4cahb0t.aspx"&gt;W4212&lt;/A&gt;: nonstandard extension used : function declaration used ellipsis&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/yshyhfby.aspx" mce_href="http://msdn.microsoft.com/en-us/library/yshyhfby.aspx"&gt;W4213&lt;/A&gt;: nonstandard extension used : cast on l-value&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/k7ea7ce7.aspx" mce_href="http://msdn.microsoft.com/en-us/library/k7ea7ce7.aspx"&gt;W4214&lt;/A&gt;: nonstandard extension used : bit field types other than int&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/00yasssw.aspx" mce_href="http://msdn.microsoft.com/en-us/library/00yasssw.aspx"&gt;W4215&lt;/A&gt;: nonstandard extension used : long float&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/477k4w1s.aspx" mce_href="http://msdn.microsoft.com/en-us/library/477k4w1s.aspx"&gt;W4216&lt;/A&gt;: nonstandard extension used : float long&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/2xye9y6s.aspx" mce_href="http://msdn.microsoft.com/en-us/library/2xye9y6s.aspx"&gt;W4218&lt;/A&gt;: nonstandard extension used : must specify at least a storage class or a type&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/d2719049.aspx" mce_href="http://msdn.microsoft.com/en-us/library/d2719049.aspx"&gt;W4221&lt;/A&gt;: nonstandard extension used : 'identifier' : cannot be initialized using address of automatic variable&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/81f5xs47.aspx" mce_href="http://msdn.microsoft.com/en-us/library/81f5xs47.aspx"&gt;W4223&lt;/A&gt;: nonstandard extension used : non-lvalue array converted to pointer&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/wh722488.aspx" mce_href="http://msdn.microsoft.com/en-us/library/wh722488.aspx"&gt;W4224&lt;/A&gt;: nonstandard extension used : formal parameter 'identifier' was previously defined as a type&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/7585wc3f.aspx" mce_href="http://msdn.microsoft.com/en-us/library/7585wc3f.aspx"&gt;W4226&lt;/A&gt;: nonstandard extension used : 'keyword' is an obsolete keyword&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/c5886yty.aspx" mce_href="http://msdn.microsoft.com/en-us/library/c5886yty.aspx"&gt;W4228&lt;/A&gt;: nonstandard extension used : qualifiers after comma in declarator list are ignored&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/9d0x3403.aspx" mce_href="http://msdn.microsoft.com/en-us/library/9d0x3403.aspx"&gt;W4231&lt;/A&gt;: nonstandard extension used : 'identifier' before template explicit instantiation&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/9a1sy630.aspx" mce_href="http://msdn.microsoft.com/en-us/library/9a1sy630.aspx"&gt;W4232&lt;/A&gt;: nonstandard extension used : 'identifier' : address of dllimport 'dllimport' is not static, identity not guaranteed&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/7ebe1389.aspx" mce_href="http://msdn.microsoft.com/en-us/library/7ebe1389.aspx"&gt;W4233&lt;/A&gt;: nonstandard extension used : 'keyword' keyword only supported in C++, not C&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/6zz25ez2.aspx" mce_href="http://msdn.microsoft.com/en-us/library/6zz25ez2.aspx"&gt;W4234&lt;/A&gt;: nonstandard extension used : 'keyword' keyword reserved for future use&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/7e5yy2kb.aspx" mce_href="http://msdn.microsoft.com/en-us/library/7e5yy2kb.aspx"&gt;W4235&lt;/A&gt;: nonstandard extension used : 'keyword' keyword not supported on this architecture&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/7zyb9yb4.aspx" mce_href="http://msdn.microsoft.com/en-us/library/7zyb9yb4.aspx"&gt;W4238&lt;/A&gt;: nonstandard extension used : &lt;STRONG&gt;class rvalue used as lvalue&lt;/STRONG&gt;&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/186yxbac.aspx" mce_href="http://msdn.microsoft.com/en-us/library/186yxbac.aspx"&gt;W4239&lt;/A&gt;: nonstandard extension used : 'token' : conversion from 'type' to 'type'&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/h2kd22yx.aspx" mce_href="http://msdn.microsoft.com/en-us/library/h2kd22yx.aspx"&gt;W4240&lt;/A&gt;: nonstandard extension used : access to 'classname' now defined to be 'access specifier', previously it was defined to be 'access specifier'&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/bk5hc10s.aspx" mce_href="http://msdn.microsoft.com/en-us/library/bk5hc10s.aspx"&gt;W4288&lt;/A&gt;: nonstandard extension used : 'var' : loop control variable declared in the for-loop is used outside the for-loop scope; it conflicts with the declaration in the outer scope&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/06d758c0.aspx" mce_href="http://msdn.microsoft.com/en-us/library/06d758c0.aspx"&gt;W4289&lt;/A&gt;: nonstandard extension used : 'var' : loop control variable declared in the for-loop is used outside the for-loop scope&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/2a68558f.aspx" mce_href="http://msdn.microsoft.com/en-us/library/2a68558f.aspx"&gt;W4353&lt;/A&gt;: nonstandard extension used: constant 0 as function expression.&amp;nbsp; Use '__noop' function intrinsic instead&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/ms173702.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms173702.aspx"&gt;W4480&lt;/A&gt;: nonstandard extension used: specifying underlying type for enum 'enum'&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/ms173703.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms173703.aspx"&gt;W4481&lt;/A&gt;: nonstandard extension used: override specifier 'keyword'&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/ms173704.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms173704.aspx"&gt;W4482&lt;/A&gt;: nonstandard extension used: enum 'enum' used in qualified name&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/syzh26ty.aspx" mce_href="http://msdn.microsoft.com/en-us/library/syzh26ty.aspx"&gt;W4509&lt;/A&gt;: nonstandard extension used: 'function' uses SEH and 'object' has destructor&lt;BR&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/ms173717.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms173717.aspx"&gt;W4836&lt;/A&gt;: nonstandard extension used : &lt;STRONG&gt;'type' : local types or unnamed types cannot be used as template arguments&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://msdn.microsoft.com/en-us/library/ft6cc9ha.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ft6cc9ha.aspx"&gt;C2599&lt;/A&gt;: &lt;STRONG&gt;'enum' : forward declaration of enum type is not allowed&lt;/STRONG&gt;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9198948" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category></item><item><title>Play with the C++ compiler - compile nightmare</title><link>http://blogs.msdn.com/xiangfan/archive/2008/09/15/play-with-the-c-compiler-compile-nightmare.aspx</link><pubDate>Mon, 15 Sep 2008 17:49:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8952632</guid><dc:creator>xiangfan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/8952632.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=8952632</wfw:commentRss><description>&lt;P&gt;Playing with the compiler is interesting. One challenge for the compiler writer is compilation performance. There're many kinds of C++ code which are the nightmare for the compiler. Now let's go! 
&lt;P&gt;1. Preprocess 
&lt;P&gt;a. Self Inclusion (GCC only)&lt;BR&gt;Normally, the compiler will limit the nest level of inclusion. In order to challenge the compiler, you have to stop the inclusion at appropriate stage. GCC provides a useful macro __INCLUDE_LEVEL__ to do the work.&lt;BR&gt;(We can write similar code for other compiler, although less elegant) 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#if&lt;/SPAN&gt; __INCLUDE_LEVEL__&amp;lt;199&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#include&lt;/SPAN&gt; __FILE__&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#include&lt;/SPAN&gt; __FILE__&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#endif&lt;/SPAN&gt;&lt;BR&gt;
&lt;P&gt;b. Macro Expansion Explosion&lt;BR&gt;By using macro, the code after the preprocess may reach O(2&lt;SUP&gt;n&lt;/SUP&gt;). For example: 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F1(x) x,x&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F2(x) F1(x),F1(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F3(x) F2(x),F2(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F4(x) F3(x),F3(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F5(x) F4(x),F4(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F6(x) F5(x),F5(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F7(x) F6(x),F6(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F8(x) F7(x),F7(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; F9(x) F8(x),F8(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G1(x) F9(x),F9(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G2(x) G1(x),G1(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G3(x) G2(x),G2(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G4(x) G3(x),G3(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G5(x) G4(x),G4(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G6(x) G5(x),G5(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G7(x) G6(x),G6(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G8(x) G7(x),G7(x)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; G9(x) G8(x),G8(x) &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; G9(1);&lt;BR&gt;}&lt;BR&gt;
&lt;P&gt;Of course, different compilers handle this kind of overflow differently. GCC will fail directly (when all of the resource are eaten up), and VC will give ICE (Internal Compiler Error). 
&lt;P&gt;2. Template 
&lt;P&gt;a. Nesting&lt;BR&gt;Similarly, there're nest level limit for template, but we can easily deceive the compiler.&lt;BR&gt;Some version of GCC will enter infinite loop when compiles the following code: 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#include&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;&amp;lt;cstddef&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt; &amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; T&amp;gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; Test {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;const&lt;/SPAN&gt; size_t Value=Test&amp;lt;Test&amp;lt;T&amp;gt; &amp;gt;::Value;&lt;BR&gt;};&lt;BR&gt;
&lt;P&gt;VC is wise enough to stop when the nest level limit is exceeded in the above code. But we can use one of VC's bug (you can also treat it as an extension) to write template which requires O(n&lt;SUP&gt;a&lt;/SUP&gt;) compilation time: 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#include&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;&amp;lt;cstddef&amp;gt;&lt;/SPAN&gt;&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; INNER(A3,N3,A2,N2) \&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;size_t N3&amp;gt;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; A3\&lt;BR&gt;{\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; {N=A3&amp;lt;N3-1&amp;gt;::N+1};\&lt;BR&gt;};\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;&amp;gt;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; A3&amp;lt;0&amp;gt;\&lt;BR&gt;{\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; {N=A2&amp;lt;N2-1&amp;gt;::N};\&lt;BR&gt;}; &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; OUTER(A2,N2,A1,N1,A3,CONTENT) \&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;size_t N2&amp;gt;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; A2\&lt;BR&gt;{\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; CONTENT\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; \&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; {N=A3&amp;lt;N2&amp;gt;::N};\&lt;BR&gt;};\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;&amp;gt;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; A2&amp;lt;0&amp;gt;\&lt;BR&gt;{\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; {N=A1&amp;lt;N1-1&amp;gt;::N};\&lt;BR&gt;}; &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; LEVEL2(a,b,c) INNER(A##b,N##b,A##a,N##a)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; LEVEL3(a,b,c) OUTER(A##b,N##b,A##a,N##a,A##c,LEVEL2(a##1,b##1,c##1))&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; LEVEL4(a,b,c) OUTER(A##b,N##b,A##a,N##a,A##c,LEVEL3(a##1,b##1,c##1))&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; LEVEL5(a,b,c) OUTER(A##b,N##b,A##a,N##a,A##c,LEVEL4(a##1,b##1,c##1)) &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;size_t N1&amp;gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; A1&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; LEVEL5(1,11,111)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; {N=A11&amp;lt;N1&amp;gt;::N};&lt;BR&gt;};&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;&amp;gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt; A1&amp;lt;0&amp;gt;&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; {N=0};&lt;BR&gt;};&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;nbsp;main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt;&amp;nbsp;A1&amp;lt;20&amp;gt;::N;&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;
&lt;P&gt;The interesting thing is that, the standard doesn't allow this kind of specialization in template class. Is this a bug or extension of VC?&lt;BR&gt;&lt;STRONG&gt;A member or a member template may be nested within many enclosing class templates. In an explicit specialization for such a member, the member declaration shall be preceded by a template&amp;lt;&amp;gt; for each enclosing class template that is explicitly specialized.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Based on similar idea, we can write portable version for both GCC and VC. &lt;/P&gt;
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;INNER(A3,N3)&amp;nbsp;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt;&amp;nbsp;N3&amp;gt;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt;&amp;nbsp;A3\&lt;BR&gt;{\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;void&lt;/SPAN&gt;&amp;nbsp;f()&amp;nbsp;{}\&lt;BR&gt;};&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;OUTER(A2,N2,A1,CONTENT)&amp;nbsp;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt;&amp;nbsp;N2&amp;gt;\&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;struct&lt;/SPAN&gt;&amp;nbsp;A2\&lt;BR&gt;{\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CONTENT\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;static&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;void&lt;/SPAN&gt;&amp;nbsp;f()&amp;nbsp;{\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;char&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;short&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;char&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;short&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;unsigned&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;long&lt;/SPAN&gt;&amp;gt;::f();\&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}\&lt;BR&gt;};&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;LEVEL2(a,b)&amp;nbsp;INNER(A##a,T##a)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;LEVEL3(a,b)&amp;nbsp;OUTER(A##a,T##a,A##b,LEVEL2(a##1,b##1))&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;LEVEL4(a,b)&amp;nbsp;OUTER(A##a,T##a,A##b,LEVEL3(a##1,b##1))&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;LEVEL5(a,b)&amp;nbsp;OUTER(A##a,T##a,A##b,LEVEL4(a##1,b##1))&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;LEVEL6(a,b)&amp;nbsp;OUTER(A##a,T##a,A##b,LEVEL5(a##1,b##1))&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;LEVEL7(a,b)&amp;nbsp;OUTER(A##a,T##a,A##b,LEVEL6(a##1,b##1))&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt;&amp;nbsp;LEVEL8(a,b)&amp;nbsp;OUTER(A##a,T##a,A##b,LEVEL7(a##1,b##1))&lt;BR&gt;&lt;BR&gt;LEVEL8(1,11)&lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;nbsp;main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A1&amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;gt;::f();&lt;BR&gt;}&lt;BR&gt;
&lt;P&gt;b. Multiple inheritance&lt;BR&gt;C++ allows multiple inheritance, it can be used to hang the compiler. Try the following "Fibonacci" inheritance: 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;size_t N&amp;gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; Evil:&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;virtual&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Evil&amp;lt;N-1&amp;gt;,&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;virtual&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt; Evil&amp;lt;N-2&amp;gt;&lt;BR&gt;{&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;public&lt;/SPAN&gt;:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;virtual&lt;/SPAN&gt; ~Evil() {}&lt;BR&gt;}; &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;&amp;gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; Evil&amp;lt;1&amp;gt;&lt;BR&gt;{&lt;BR&gt;};&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt;&amp;lt;&amp;gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; Evil&amp;lt;0&amp;gt;&lt;BR&gt;{&lt;BR&gt;}; &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Evil&amp;lt;100&amp;gt; evil;&lt;BR&gt;}&lt;BR&gt;
&lt;P&gt;c. OLE (Output limit exceeded)&lt;BR&gt;Normally, the compile time for template is O(n), but in contrast, the amount of error message will be O(n&lt;SUP&gt;2&lt;/SUP&gt;). Taking advantage of this, you can make the error message "Output Limit Exceeded". For example: 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#define&lt;/SPAN&gt; ClassName A &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;template&lt;/SPAN&gt; &amp;lt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; N&amp;gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;class&lt;/SPAN&gt; ClassName&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;enum&lt;/SPAN&gt; {Value=ClassName&amp;lt;N-1&amp;gt;::Value};&lt;BR&gt;}; &lt;BR&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt; n=ClassName&amp;lt;0&amp;gt;::Value;&lt;BR&gt;} 
&lt;P&gt;If I change "ClassName" to a very long name (which is widely supported by modern compilers), the error message will be easily OLE.&lt;BR&gt;PS: The above code will cause ICE in VC8. This is the bug of VC8, and VC9 is happy with the code.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8952632" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/Bug/default.aspx">Bug</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/GCC/default.aspx">GCC</category></item><item><title>Debug vs Release</title><link>http://blogs.msdn.com/xiangfan/archive/2008/08/30/debug-vs-release.aspx</link><pubDate>Sat, 30 Aug 2008 15:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8909489</guid><dc:creator>xiangfan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/8909489.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=8909489</wfw:commentRss><description>&lt;P&gt;Someone may wonder what the difference is between Debug and Release mode, and whether it is possible to mix them. 
&lt;P&gt;Here is one example: &lt;A href="http://forums.msdn.microsoft.com/en-US/vcgeneral/thread/775ce067-b225-4141-8b86-2d7e9b61db97/" mce_href="http://forums.msdn.microsoft.com/en-US/vcgeneral/thread/775ce067-b225-4141-8b86-2d7e9b61db97/"&gt;http://forums.msdn.microsoft.com/en-US/vcgeneral/thread/775ce067-b225-4141-8b86-2d7e9b61db97/&lt;/A&gt; 
&lt;P&gt;syperk said: "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.". 
&lt;P&gt;But that is not true. There are many problems. In my opion, the most important one is that it is not a good idea to link different modules compiled with different compiler options in C++, especially when conditional compilation is involved. 
&lt;P&gt;In fact, "Debug" &amp;amp; "Release" are only two sets of predefined compiler flags and macros definitions provided by the IDE (_DEBUG and NDEBUG are two representing macros). The compiler doesn't aware of that (but it has some magic behind compile option "MD" and "MDd").&lt;BR&gt;The main problem is that program compiled using "Debug" setting and the release runtime don't share the same compiler flags, and they are highly possible to be incompatible. 
&lt;P&gt;For example, if you change "MDd" -&amp;gt; "MD" in your debug configuration, and compile the following code (don't remove the _DEBUG macro, otherwise the "Debug" version is no longer a debug version (/MDd will define this macro implicitly, and IDE will explicitly define it via compiler flag)) : 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#include&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;&amp;lt;iostream&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#include&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;&amp;lt;string&amp;gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;using&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;namespace&lt;/SPAN&gt;&amp;nbsp;std;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;int&lt;/SPAN&gt;&amp;nbsp;main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;std::string&amp;nbsp;str;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;return&lt;/SPAN&gt;&amp;nbsp;0;&lt;BR&gt;}&lt;BR&gt;&lt;BR&gt;
&lt;P&gt;You'll find that the program function properly. If you check the generated exe, you'll find that it refer to two dlls, one is msvcp90d.dll, the other is msvcr90.dll. Oops! You're mixing the debug and release runtime libraries! And that hide the potential incompatibility! 
&lt;P&gt;The magic is here (in use_ansi.h): 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#ifdef&lt;/SPAN&gt;&amp;nbsp;_DEBUG&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#pragma&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;comment&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;lib&lt;/SPAN&gt;,&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"msvcprtd"&lt;/SPAN&gt;)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#else&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/*&amp;nbsp;_DEBUG&amp;nbsp;*/&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#pragma&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;comment&lt;/SPAN&gt;(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;lib&lt;/SPAN&gt;,&lt;SPAN style="COLOR: rgb(163,21,21)"&gt;"msvcprt"&lt;/SPAN&gt;)&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;#endif&lt;/SPAN&gt;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;/*&amp;nbsp;_DEBUG&amp;nbsp;*/&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;&lt;/SPAN&gt;&lt;BR&gt;
&lt;P&gt;If you disable this trick, and link to msvcp90.dll, you'll get unresolved symbol error, that is because the implementation of string class is different in "Debug" and "Release" mode. This is one example of the incompatibility. 
&lt;P&gt;error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall std::basic_string&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt;,class std::allocator&amp;lt;char&amp;gt; &amp;gt;::basic_string&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt;,class std::allocator&amp;lt;char&amp;gt; &amp;gt;(struct std::basic_string&amp;lt;char,struct std::char_traits&amp;lt;char&amp;gt;,class std::allocator&amp;lt;char&amp;gt; &amp;gt;::_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 
&lt;P&gt;It's fortunate that this is a linker error. Otherwise, you'll waste lots of time in debugging to find out the subtle incompatibility. 
&lt;P&gt;STL in VC9 devotes lots of efforts to prevent break like this, then you can disable macros like "_HAS_ITERATOR_DEBUGGING" as you like, and keep your code compatible with the runtime (which is compiled with the macro enabled). But it only applies when you stick to debug or stick to release. It is really tricky to guarantee that, and I think you should never rely on this.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8909489" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category></item><item><title>Conformance macros in VC STL</title><link>http://blogs.msdn.com/xiangfan/archive/2008/08/30/conformance-macros-in-vc-stl.aspx</link><pubDate>Sat, 30 Aug 2008 11:01:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8908873</guid><dc:creator>xiangfan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/8908873.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=8908873</wfw:commentRss><description>&lt;P&gt;In VC STL, there are two macros called "_HAS_IMMUTABLE_SETS" and "_HAS_STRICT_CONFORMANCE" which are defined in yvals.h. They are related to some defects in the C++ standard 2003. 
&lt;P&gt;1. _HAS_IMMUTABLE_SETS will influence the constness of set::iterator. 
&lt;P&gt;Associative containers require its elements to be sorted, so modify them will be dangerous. But the standard doesn't prohibit the programmer to do that. 
&lt;P&gt;In C++0x, the following statement is added for associative containter:&lt;BR&gt;For associative containers where the value type is the same as the key type, both iterator and const_iterator are constant iterators&lt;BR&gt;(In the standard, it is said:&lt;BR&gt;Constant iterators do not satisfy the requirements for output iterators, and the result of the expression *i (for constant iterator i) cannot be used in an expression where an lvalue is required.)&lt;BR&gt;That means you cannot modify the value of the elements using iterator any more. 
&lt;P&gt;Discussion: &lt;A href="http://www.cpptalk.net/image-vp135370.html" mce_href="http://www.cpptalk.net/image-vp135370.html"&gt;http://www.cpptalk.net/image-vp135370.html&lt;/A&gt; 
&lt;P&gt;2. _HAS_STRICT_CONFORMANCE will influence two places: 
&lt;P&gt;a. For set, multiset, map and multimap 
&lt;P&gt;void erase(const_iterator position);&lt;BR&gt;size_type erase(const key_type&amp;amp; x);&lt;BR&gt;void erase(const_iterator first, const_iterator last); 
&lt;P&gt;-&amp;gt; 
&lt;P&gt;iterator erase(const_iterator position);&lt;BR&gt;size_type erase(const key_type&amp;amp; x);&lt;BR&gt;iterator erase(const_iterator first, const_iterator last); 
&lt;P&gt;In C++03, erase in associative containers will not return the iterator, which is incompatible with sequence containers. It is fixed in C++0x&lt;BR&gt;VC's extension provides the return value for erase. _HAS_STRICT_CONFORMANCE will disable this extension. 
&lt;P&gt;Discussion: &lt;A href="http://www.tech-archive.net/Archive/VC/microsoft.public.vc.stl/2005-10/msg00030.html" mce_href="http://www.tech-archive.net/Archive/VC/microsoft.public.vc.stl/2005-10/msg00030.html"&gt;http://www.tech-archive.net/Archive/VC/microsoft.public.vc.stl/2005-10/msg00030.html&lt;/A&gt;&lt;BR&gt;Further Discussion: &lt;A href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103" mce_href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103"&gt;http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103&lt;/A&gt; 
&lt;P&gt;b. For codecvt::do_length(stateT&amp;amp; state, const externT* from, const externT* from_end, size_t max) const; 
&lt;P&gt;In C++03, codecvt&amp;lt;wchar_t, char, mbstate_t&amp;gt; and codecvt&amp;lt;char, char, mbstate_t&amp;gt; should return the lesser of max and (from_end-from).&lt;BR&gt;This is weakened in C++0x. Only codecvt&amp;lt;char, char, mbstate_t&amp;gt; is required to behave like that. 
&lt;P&gt;BTW: VC's STL implementation is provided by Dinkumware. You can see "P.J. Plauger" at the end of each STL file. &lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8908873" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/VC/default.aspx">VC</category></item></channel></rss>