<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.atalasoft.com/cs/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>Steve's Tech Talk : design, compiler, C++, C#, code</title><link>http://www.atalasoft.com/cs/blogs/stevehawley/archive/tags/design/compiler/C_2B002B00_/C_2300_/code/default.aspx</link><description>Tags: design, compiler, C++, C#, code</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>How I Learned to Start Worrying and Distrust the Bomb</title><link>http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx</link><pubDate>Tue, 07 Jul 2009 15:07:00 GMT</pubDate><guid isPermaLink="false">647108ca-f046-4d8d-9feb-a7fbd2049b37:18787</guid><dc:creator>Steve Hawley</dc:creator><slash:comments>0</slash:comments><comments>http://www.atalasoft.com/cs/blogs/stevehawley/comments/18787.aspx</comments><wfw:commentRss>http://www.atalasoft.com/cs/blogs/stevehawley/commentrss.aspx?PostID=18787</wfw:commentRss><description>&lt;p&gt;This is a post about a serious bug I turned up in the Microsoft C++ compilers that target CLI (both Managed C++ and C++/CLI).&lt;/p&gt;  &lt;p&gt;One of the key concepts in software engineering is &lt;a href="http://en.wikipedia.org/wiki/Design_by_contract"&gt;Design by Contract&lt;/a&gt;.&amp;#160; Design by Contract boils down to “say what you do and do what you say.”&amp;#160; Essentially, when I make a semantic definition, I would like it to be abided by the providers and when applicable the clients of the definition.&amp;#160; For example, if I define a language runtime I can define arrays such that indexing into the array must always be range checked.&amp;#160; I can enforce this limitation at a number of levels.&amp;#160; For example, I can provide a runtime array API which includes range checking in all its members.&amp;#160; This is the simplest approach, but probably the most inefficient.&amp;#160; I could also leave it up to the compiler writers to check before calling the API – this is potentially more efficient because it allows loop invariant optimization.&amp;#160; If I’m looping over all elements in an array, I know that if the loop extents are within the range of the given array, then all indexing based on the unchanged loop variable(s) will also be in range.&lt;/p&gt;  &lt;p&gt;The problem with putting the onus of checking on the compiler writers is that the adherence to the contract is only as good as the diligence of the compiler writers and the verifiers of the compiler (unit tests, qa, outside certification).&lt;/p&gt;  &lt;p&gt;I discovered early on that there was a certain amount of looseness in what appear to be iron rules.&amp;#160; For example, from the point of view of Managed C++, there is &lt;a href="http://www.atalasoft.com/cs/blogs/stevehawley/archive/2008/04/18/out-out-damn-ref.aspx"&gt;no difference between out and ref parameters&lt;/a&gt;, whereas C# demands that assignment is done to an out parameter in all code paths.&lt;/p&gt;  &lt;p&gt;So let’s consider one of the nicest conventions added to .NET for those of us (like &lt;a href="http://www.atalasoft.com"&gt;Atalasoft&lt;/a&gt;) who write class libraries for others to use: ObsoleteAttribute.&lt;/p&gt;  &lt;p&gt;By added an Obsolete to a class or method, I can signal my clients that a particular feature is no longer considered to be the “right” way to do something.&amp;#160; I may have written a more flexible way to get the same feature.&amp;#160; Obsolete lets me communicate that to my clients.&amp;#160; In the message that will be passed on by the compiler, I can let my clients know that there is a better way.&amp;#160; And it, heaven forbid, I have to revoke access to a feature, I can force an error at compile time.&amp;#160; I like this – especially at the piecemeal level of attributes that I can tack onto classes, methods, properties, fields, etc.&amp;#160; In C, there isn’t a really good way to do this except via #error and #warning, which can’t be used with the same granularity without some heavy preprocessor lifting.&lt;/p&gt;  &lt;p&gt;So let’s consider this awful C# class:&lt;/p&gt;  &lt;pre style="border-right:#cecece 1px solid;padding-right:5px;border-top:#cecece 1px solid;padding-left:5px;min-height:40px;padding-bottom:5px;overflow:auto;border-left:#cecece 1px solid;width:650px;padding-top:5px;border-bottom:#cecece 1px solid;background-color:#fbfbfb;"&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; Helpers
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;{
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Utilities
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    {
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;        [Obsolete(&amp;quot;&lt;span style="color:#8b0000;"&gt;This is really not needed.&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Add(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; a, &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; b)
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;        {
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; a + b;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;        }
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;        [Obsolete(&amp;quot;&lt;span style="color:#8b0000;"&gt;This is a horrible constant.&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Pi { &lt;span style="color:#0000ff;"&gt;get&lt;/span&gt; { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; 3; } }
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    }
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This is a class with a static method and a property.&amp;#160; Both are marked as obsolete and both are marked to fail when used.&lt;/p&gt;

&lt;p&gt;If I try to use either of these in C#, the compiler fails with an error.&amp;#160; Good.&amp;#160; Now comes the problem: C++.&amp;#160; Consider this chunk of test code:&lt;/p&gt;

&lt;pre style="border-right:#cecece 1px solid;padding-right:5px;border-top:#cecece 1px solid;padding-left:5px;min-height:40px;padding-bottom:5px;overflow:auto;border-left:#cecece 1px solid;width:650px;padding-top:5px;border-bottom:#cecece 1px solid;background-color:#fbfbfb;"&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;#include &amp;quot;&lt;span style="color:#8b0000;"&gt;stdafx.h&lt;/span&gt;&amp;quot;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; System;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;#&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; MANAGED_CPP
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; main(System::String __gc *args __gc[])
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;#&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; main(array&amp;lt;System::String ^&amp;gt; ^args)
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;#endif
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;{
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;span style="color:#008000;"&gt;// Fails at compile time&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;span style="color:#008000;"&gt;//    int sum = Helpers::Utilities::Add(3, 4);&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; sum = 0;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;#&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; MANAGED_CPP
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    Helpers::Utilities *u = __gc &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Helpers::Utilities();
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    sum += u-&amp;gt;get_Pi();
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;#&lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    Helpers::Utilities ^u = gcnew Helpers::Utilities();
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    sum += u-&amp;gt;Pi::get();
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;#endif
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    sum += u-&amp;gt;Pi;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; 0;
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;}
&lt;/pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;background-color:#fbfbfb;"&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;This code is a little sloppy because I wrote it to be testable from either managed C++ or C++/CLI.&amp;#160; Even though the syntax is different, the result is the same.&amp;#160; If I try to call Add, I’ll get a compilation error.&amp;#160; Good.&amp;#160; The problem comes with accessing the property Pi.&amp;#160; The C# class has explicitly forbidden the use of the property, yet when I compile this code with either compiler it blissfully succeeds (“========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========”).&amp;#160; Not only that, it runs.&amp;#160; Yikes.&lt;/p&gt;

&lt;p&gt;Take the Obsolete attribute with a grain of salt.&amp;#160; It is a contract, yes, but it only works as well as those who adhere to it.&amp;#160; If you create a property that you want to be truly obsolete and cause compile failures, consider removing it entirely.&amp;#160;&amp;#160; I don’t like this – it fails compilation everywhere, but we also lose the ability to tell our clients what they should do instead.&amp;#160; You could also change the behavior to a runtime throw with an appropriate message in addition to the obsolete attribute.&amp;#160; I don’t like this either as I’m creating time bombs for my C++ clients, but at least they can’t cause other problems which could be much worse.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a href = "mailto:?body=Thought you might like this: http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx&amp;amp;;subject=How+I+Learned+to+Start+Worrying+and+Distrust+the+Bomb" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx"&gt;email it!&lt;/a&gt; |  &lt;a href = "http://del.icio.us/post?url=http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx&amp;amp;;title=How+I+Learned+to+Start+Worrying+and+Distrust+the+Bomb" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx"&gt;bookmark it!&lt;/a&gt; |  &lt;a href = "http://www.digg.com/submit?url=http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx&amp;amp;;phase=2" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx"&gt;digg it!&lt;/a&gt; |  &lt;a href = "http://reddit.com/submit?url=http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx&amp;amp;title=How+I+Learned+to+Start+Worrying+and+Distrust+the+Bomb" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx"&gt;reddit!&lt;/a&gt; |  &lt;a href = "http://www.dotnetkicks.com/submit/?url=http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx&amp;amp;;title=How+I+Learned+to+Start+Worrying+and+Distrust+the+Bomb" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx"&gt;kick it!&lt;/a&gt; |  &lt;a href = "https://favorites.live.com/quickadd.aspx?marklet=1&amp;amp;;mkt=en-us&amp;amp;;url=http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx&amp;amp;;title=How+I+Learned+to+Start+Worrying+and+Distrust+the+Bomb&amp;amp;;top=1" target="_blank" title = "Post http://www.atalasoft.com/cs/blogs/stevehawley/archive/2009/07/07/how-i-learned-to-start-worrying-and-distrust-the-bomb.aspx"&gt;live it!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.atalasoft.com/cs/aggbug.aspx?PostID=18787" width="1" height="1"&gt;</description><category domain="http://www.atalasoft.com/cs/blogs/stevehawley/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://www.atalasoft.com/cs/blogs/stevehawley/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://www.atalasoft.com/cs/blogs/stevehawley/archive/tags/code/default.aspx">code</category><category domain="http://www.atalasoft.com/cs/blogs/stevehawley/archive/tags/design/default.aspx">design</category><category domain="http://www.atalasoft.com/cs/blogs/stevehawley/archive/tags/compiler/default.aspx">compiler</category></item></channel></rss>