<?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 : Bug</title><link>http://blogs.msdn.com/xiangfan/archive/tags/Bug/default.aspx</link><description>Tags: Bug</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><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>Magic behind ValueType.Equals</title><link>http://blogs.msdn.com/xiangfan/archive/2008/09/01/magic-behind-valuetype-equals.aspx</link><pubDate>Mon, 01 Sep 2008 18:35:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8916815</guid><dc:creator>xiangfan</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/xiangfan/comments/8916815.aspx</comments><wfw:commentRss>http://blogs.msdn.com/xiangfan/commentrss.aspx?PostID=8916815</wfw:commentRss><description>&lt;P&gt;In "Effective C#", Bill Wagner says "Always create an override of ValueType.Equals() whenever you create a value type". His main consideration is the performance, because reflection is needed to compare two value types memberwisely. 
&lt;P&gt;In fact, the framework provides optimization for "simple" value type. Let's find out the magic. 
&lt;P&gt;Here is the code disassembled by Reflector: 
&lt;P&gt;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;bool&lt;/SPAN&gt;&amp;nbsp;Equals(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;object&lt;/SPAN&gt;&amp;nbsp;obj)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;//Compare&amp;nbsp;type&amp;nbsp;&lt;/SPAN&gt;&lt;BR&gt;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;&lt;/SPAN&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;object&lt;/SPAN&gt;&amp;nbsp;a&amp;nbsp;=&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;if&lt;/SPAN&gt;&amp;nbsp;(CanCompareBits(&lt;SPAN style="COLOR: rgb(0,0,255)"&gt;this&lt;/SPAN&gt;))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&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;&amp;nbsp;FastEqualsCheck(a,&amp;nbsp;obj);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;BR&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;SPAN style="COLOR: rgb(0,128,0)"&gt;//Compare&amp;nbsp;using&amp;nbsp;reflection&lt;/SPAN&gt;&lt;BR&gt;}&lt;BR&gt;
&lt;P&gt;The magic is the two functions "CanCompareBits" and "FastEqualsCheck". They both have attribute "[MethodImpl(MethodImplOptions.InternalCall)]", which indicates that their implementations are in native dlls. 
&lt;P&gt;Walkthrough the source of &lt;A href="http://research.microsoft.com/sscli/" mce_href="http://research.microsoft.com/sscli/"&gt;rotor&lt;/A&gt;, you can find that these functions are in "clr\src\vm\comutilnative.cpp" 
&lt;P&gt;The comment of CanCompareBits says "Return true if the valuetype does not contain pointer and is tightly packed". And FastEqualsCheck use "memcmp" to speed up the comparison. 
&lt;P&gt;Then you may think you can safely rely on this optimization and stick to the default ValueType.Equals implementation. But wait a minute. Do you find anything wrong in CanCompareBits? 
&lt;P&gt;The problem is that the condition in the comment doesn't ensure the bitwise comparison to work. 
&lt;P&gt;Imagine you have a structure which only contains a float. What will occur if one contains +0.0, and the other contains -0.0? They should be the same, but the underlying binary representation are different.&lt;BR&gt;If you nest other structure which override the Equals method, that optimization will also fail. 
&lt;P&gt;This should be a bug. But it also provide another reason for why you should always implement your own instance Equals for ValueType.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8916815" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/xiangfan/archive/tags/Optimization/default.aspx">Optimization</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/Bug/default.aspx">Bug</category><category domain="http://blogs.msdn.com/xiangfan/archive/tags/C_2300_/default.aspx">C#</category></item></channel></rss>