<?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>C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx</link><description>Raymond has an interesting post today about two subtle aspects of C#: how order of evaluation in an expression is specified as strictly left-to-right, and how the rules regarding local shadowing ensure that an identifier has exactly one meaning in a local</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4388373</link><pubDate>Tue, 14 Aug 2007 22:37:11 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4388373</guid><dc:creator>Jon Skeet</dc:creator><description>&lt;p&gt;Eric, I wonder if you'd think about covering one situation which Neal's post didn't tackle: the situation where there are no bugs in the existing compiler, but the specification changes so that the behaviour of compiling code in version N is different to the compiling code in version N+1.&lt;/p&gt;
&lt;p&gt;The only example I can immediately think of in C# is where delegate parameter contravariance allows for more methods to be included in a method group as valid conversions, leading to a breaking change in some very specific situations. The C# 2+ compiler warns of this change, thankfully - I wonder if there are any cases which don't have warnings?&lt;/p&gt;
&lt;p&gt;Anyway, I for one would find discussion of that topic fascinating :)&lt;/p&gt;
&lt;p&gt;Jon&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4388575</link><pubDate>Tue, 14 Aug 2007 22:48:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4388575</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;Commander Riker, you have anticipated my denouement. &lt;/p&gt;
&lt;p&gt;Those are exactly the sorts of subtle breaking changes I had in mind. &amp;nbsp;The semantics of lambda conversion will likely introduce more in C# 4.0, particularly if we introduce other kinds of variance.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4391714</link><pubDate>Wed, 15 Aug 2007 02:10:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4391714</guid><dc:creator>Edd</dc:creator><description>&lt;p&gt;&amp;quot;1. the vast majority of the time it makes no difference&amp;quot;&lt;/p&gt;
&lt;p&gt;So people like to think :( &lt;/p&gt;
&lt;p&gt;I would argue that this really isn't the case. See below...&lt;/p&gt;
&lt;p&gt;&amp;quot;2. relying on a particular timing or ordering of finalization some small percentage of the time is probably a subtle bug waiting to happen&amp;quot;&lt;/p&gt;
&lt;p&gt;On the other hand, by not having deterministic finialization/destruction, it is an order of magnitude more difficult to write exception safe code without putting in additional scaffolding everywhere in your code. IMHO, using/IDisposable are staples of any robust C# program. Without them a program may have innumerable hidden bugs, just waiting to jump out of the woodwork when deployed on a customer's 'foreign' system.&lt;/p&gt;
&lt;p&gt;&amp;quot;4. specifying it ties our hands to make algorithm improvements in the future&amp;quot;&lt;/p&gt;
&lt;p&gt;Huh?&lt;/p&gt;
&lt;p&gt;Don't get me wrong, I'm not anti-GC/nondeterministic finalisation, but there's a lot of subtlety that exists as a side-effect of the feature that needs to be grasped in order to write robust code. &lt;/p&gt;
&lt;p&gt;Some might argue that it takes as much effort to educate C# users about writing exception-safe code as it does to educate C++ users how to use the standard library and modern techniques so as to completely avoid the C++ errors you mentioned (I can honestly say I haven't had a memory leak in any of the C++ code I've written in the last 3 years, just by making sure I write code in a modern way).&lt;/p&gt;
&lt;p&gt;I just thought the trade-off needed to be mentioned. In either language, I would say that education is the real issue.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4392540</link><pubDate>Wed, 15 Aug 2007 03:00:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4392540</guid><dc:creator>Nevin ":-)" Liber</dc:creator><description>&lt;p&gt;C'mon, this is just rationalization.&lt;/p&gt;
&lt;p&gt;Unspecified order of evaluation: &amp;nbsp;bad.&lt;/p&gt;
&lt;p&gt;Unspecified order of finalization: &amp;nbsp;good.&lt;/p&gt;
&lt;p&gt;Yeah, right.&lt;/p&gt;
&lt;p&gt;Don't all the minuses for the unspecified order of evaluation also apply to the unspecified order of finalization? &amp;nbsp;Why is finalization order easy on the language implementation team while evaluation order is hard on them? &amp;nbsp;Same thing about testers. &amp;nbsp;Etc., etc.&lt;/p&gt;
&lt;p&gt;As for buffer overruns, memory leaks, double frees, etc., well, if you are basically writing C code in C++ (and calling them double frees instead of double deletes certainly hints at that), of course you still get these problems on a very regular basis. &amp;nbsp;Embrace more modern C++ (vectors instead of arrays, algorithms instead of hand-coded loops, smart pointers instead of manual memory management, references instead of pointers, etc.) and most of these issues just don't happen.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4401590</link><pubDate>Wed, 15 Aug 2007 18:08:29 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4401590</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;&amp;gt; Don't all the minuses for the unspecified order of evaluation also apply to the unspecified order of finalization&lt;/p&gt;
&lt;p&gt;Yes. But the benefits of nondeterministic finalization outweigh the costs. The benefits of unspecified order of evaluation do not.&lt;/p&gt;
&lt;p&gt;&amp;gt; Embrace more modern C++&lt;/p&gt;
&lt;p&gt;If I wrote only new C++ code, absolutely. I happen to work in code that is seven to fifteen years old and was written by large teams of people, many of whom had their own ideas of what &amp;quot;modern&amp;quot; code looks like. Some of the hardest bugs I've had to fix have been where people mixed &amp;quot;modern&amp;quot; idioms into old code and did not understand the subtle assumptions about memory model made by each. I hope you never have to experience the pain of having to clone a multithreaded COM object containing a vector of smart pointers to BSTRs!&lt;/p&gt;
&lt;p&gt;That is another one of the huge benefits of C# and the CLR -- one memory model, one finalization model, one string class, etc. &lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4401639</link><pubDate>Wed, 15 Aug 2007 18:12:30 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4401639</guid><dc:creator>Dave</dc:creator><description>&lt;p&gt;I have to agree with Nevin. I'd rather debug a C++ sequence point bug like (++i) + i + (i++) because it's usually out in the open on one line, with no complex time-domain dependencies. Raymond had a related post today.&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/oldnewthing/archive/2007/08/15/4392538.aspx"&gt;http://blogs.msdn.com/oldnewthing/archive/2007/08/15/4392538.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With C# I can't be sure when my class will be created *or* destroyed. Now that's uncertainty leading to despair, or at least to long debugging sessions.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4401648</link><pubDate>Wed, 15 Aug 2007 18:13:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4401648</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;Re: Huh?&lt;/p&gt;
&lt;p&gt;The VB6 GC algorithm is well known. &amp;nbsp;We can never change it because people have written massive production systems which depend upon that algorithm staying the same forever. &lt;/p&gt;
&lt;p&gt;The CLR GC algorithm documentation is deliberately vague. If our research shows that four generations would be more efficient than three, we can change it. If our research shows that the version of the CLR which runs on small devices would work better with a train collector than a mark-n-sweep collector, we can change it. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;When we document an algorithm, we are telling people that they can depend on that, and that prevents us from making improvements in the future. We would like to be able to make improvements to the GC. This is an area of active research and we can probably do better.&lt;/p&gt;
&lt;p&gt;Of course, even when we deliberately document the fact that an algorithm WILL change in a future version and you must NOT rely upon it staying the same -- as we did for the hash code algorithm -- people still do rely on it, and then they complain when their code breaks. To me.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4401666</link><pubDate>Wed, 15 Aug 2007 18:16:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4401666</guid><dc:creator>Yuhong Bao</dc:creator><description>&lt;p&gt;But this isn't about destruction, it is about creation.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4411189</link><pubDate>Thu, 16 Aug 2007 09:43:24 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4411189</guid><dc:creator>Tanveer Badar</dc:creator><description>&lt;p&gt;Eric did you know your blog counts as a security related blog too? :)&lt;/p&gt;
&lt;p&gt;Today I received a news letter (Microsoft Security Newsletter - Volume 4, Issue 8) from Microsoft which lists your blog as one of 'Security Blogs'!&lt;/p&gt;
&lt;p&gt;You have about 29 entries tagged as 'Security' out of the hundreds.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4414366</link><pubDate>Thu, 16 Aug 2007 15:35:40 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4414366</guid><dc:creator>dal</dc:creator><description>&lt;p&gt;Eric,&lt;/p&gt;
&lt;p&gt;I use Dispose and using statements everywhere; it is the best choice available, but...&lt;/p&gt;
&lt;p&gt;...you made the statement that &amp;quot;But we do provide a mechanism (the &amp;quot;using&amp;quot; statement) whereby if you do need to ensure that a finalizer runs at a particular point, there is an easy syntax for it.&amp;quot;&lt;/p&gt;
&lt;p&gt;I don't mean to sound pedantic but this statement is false. All that the using statement does is invoke a user-defined method &amp;quot;Dispose&amp;quot; that takes no arguments. It also requires that the object implement the IDisposable interface, and there are many objects, many of them sealed, that do not. Within the Dispose method it is entirely up to the user to ensure that proper cleanup occurs. &lt;/p&gt;
&lt;p&gt;It is also up to the user to invoke GC.SupressFinalize(this), which actually prevents the finalizer from being invoked. &amp;nbsp;In fact, I don't think you'd reach complete consensus on whether the call to GC.SupressFinalize(this) should occur before or after normal cleanup in Dispose has finished. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;There is a great deal of scaffolding that has been built on top of this, with lots of best practices and assumptions baked into the conversations, and I've seen many examples which work...about 98% of the time and far less than that under abnormal shutdown. Depending on the circumstances, anything can fail, even a call to Trace(). &amp;nbsp;I've examined a lot of code in Dispose methods that simply did not work correctly under all use-cases.&lt;/p&gt;
&lt;p&gt;It is incredibly difficult to write &amp;nbsp;a correct Dispose method that accounts for all the different environments and circumstances it can be invoked in, all the things that can go wrong, and which is robust and resilient in the face of unexpected failures. &lt;/p&gt;
&lt;p&gt;I think an interesting question is if a Dispose method can run simultaneously with a finalizer (I think it can).&lt;/p&gt;
&lt;p&gt;I think the situation is far better than in C++ and COM, and I'd rather write C# than anything else (right now) but it is a work in progress. I think that the current semantics of shutdown/cleanup/finalization works well for a certain type of application but is not well suited for others.&lt;/p&gt;
&lt;p&gt;About order of evaluation....I hate programs that rely on it. I would much prefer to look at code like this:&lt;/p&gt;
&lt;p&gt;x + (y * z) &lt;/p&gt;
&lt;p&gt;than&lt;/p&gt;
&lt;p&gt;x + y * z&lt;/p&gt;
&lt;p&gt;I don't want to have to spend time reasoning about order of evaluation -it's just one more thing to get wrong. &amp;nbsp;I'd even rather have the compiler issue a warning about code like that, because I'd bet that most of the time the developer did not even realize that it was a possible problem. My motto: &amp;quot;parentheses everywhere&amp;quot; &lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4415952</link><pubDate>Thu, 16 Aug 2007 17:22:58 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4415952</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;Tanveer: &amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;gt; Eric did you know your blog counts as a security related blog too?&lt;/p&gt;
&lt;p&gt;Yes, I knew that. I put my blog on that list.&lt;/p&gt;
&lt;p&gt;&amp;gt; You have about 29 entries tagged as 'Security' out of the hundreds.&lt;/p&gt;
&lt;p&gt;That is correct.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4416083</link><pubDate>Thu, 16 Aug 2007 17:31:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4416083</guid><dc:creator>Eric Lippert</dc:creator><description>&lt;p&gt;dal:&lt;/p&gt;
&lt;p&gt;I absolutely agree that the correct implementation of the disposable pattern is excessively complex and error-prone. This is one of those places where we make it easy to get it wrong. If anyone has suggestions for how we could make it better, I'd love to hear them.&lt;/p&gt;
&lt;p&gt;Your remark about parens is a bit confusing. Parentheses do not affect order of evaluation at all. Order of evaluation is left-to-right no matter where the parens are. &amp;nbsp;eg, A() + (B() + C()) calls A, B, C in that order. &lt;/p&gt;
&lt;p&gt;I think you have confused order of evaluation with operator precedence. If you are in fact talking about operator precedence, then yes, I agree with you, it is often hard to read code which relies upon the reader knowing the precedence rules. Most readers know that * binds tighter than +, but I can never remember whether &amp;lt;&amp;lt; binds tighter than &amp;amp;, for instance. I always parenthesize anything involving an &amp;quot;unusual&amp;quot; operator.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4672756</link><pubDate>Fri, 31 Aug 2007 20:57:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4672756</guid><dc:creator>David Jones</dc:creator><description>&lt;p&gt;I generally agree with the main points of the post but I found this to be a little bit surprising:&lt;/p&gt;
&lt;p&gt;&amp;#171;People entrust the operation of multi-million dollar businesses to their C# code; they're not going to do that if we can't even reliably tell them what &amp;quot;(++i) + i + (i++)&amp;quot; does&amp;#187;&lt;/p&gt;
&lt;p&gt;Well, C never told anyone what &amp;quot;(++i) + i + (i++)&amp;quot; does but plenty of people went off to build multi-million dollar businesses on top of it. &amp;nbsp;Microsoft included.&lt;/p&gt;
&lt;p&gt;I see lots of people confusing finalization with destruction. &amp;nbsp;There's an old chestnut.&lt;/p&gt;
</description></item><item><title>re: C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4676343</link><pubDate>Sat, 01 Sep 2007 00:40:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4676343</guid><dc:creator>Anonymous Cowherd</dc:creator><description>&lt;p&gt; Nondeterministic order of evaluation in C and C++ is (also) a good example. We deliberately do not specify when and in what order the operands are evaluated in most expressions (with the obvious exception of ?: and the comma operator) because:&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 1. the vast majority of the time it makes no difference (seriously, how often do you write (f()+g()) with the expectation that f() will happen first?),&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 2. relying on a particular timing or ordering of operations some small percentage of the time is probably a subtle bug waiting to happen (see above),&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 3. specifying it would require us to simplify the implementation to the point where it actually could be specified, thereby destroying much of its value; there is value in that complexity (namely optimizations such as constant-folding)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; 4. specifying it ties our hands to make optimizations in the future (such as instruction pipelining and CSE)&lt;/p&gt;
&lt;p&gt;But we do provide a mechanism (the assignment statement) whereby if you do need to ensure that an expression is evaluated at a particular point, there is an easy syntax for it.&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;int evaluated_first = f();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;result = evaluated_first + g();&lt;/p&gt;
&lt;p&gt;People entrust the operation of multi-million dollar businesses to their C and C++ code; they might have second thoughts about it if we shut the door to so many optimizations that we could presume to tell them reliably what &amp;quot;(++i) + i + (i++)&amp;quot; must do!&lt;/p&gt;
&lt;p&gt;Eric, I think you should have been pointing to *better static analysis* as the silver bullet, not to more-restrictive language specifications. If the programmer gives &amp;quot;(++i) + i + (i++)&amp;quot; to the compiler, he'd better receive a slap on the wrist; the compiler should not silently accept such obviously bogus code, never mind what the standards committee thought the &amp;quot;intuitive&amp;quot; codegen for it might be. &amp;nbsp;C and C++ permit the compiler to dole out such slaps at compile-time. C#, by defining an &amp;quot;intuitive&amp;quot; meaning for the bogus code, seems to prohibit such slaps, which to me would seem to lead to more-fragile coding practices, never mind the reduced possibilities for compiler optimization.&lt;/p&gt;
</description></item><item><title>Falling Into The Pit of Success</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx#4928990</link><pubDate>Sat, 15 Sep 2007 18:07:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4928990</guid><dc:creator>Programming</dc:creator><description>&lt;p&gt;Eric Lippert notes the perils of programming in C++ : I often think of C++ as my own personal Pit of&lt;/p&gt;
</description></item></channel></rss>