<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Fabulous Adventures In Coding</title><subtitle type="html">Eric Lippert's Blog</subtitle><id>http://blogs.msdn.com/ericlippert/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/ericlippert/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2009-10-12T06:51:00Z</updated><entry><title>What's the difference between covariance and assignment compatibility?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx</id><published>2009-11-30T14:51:00Z</published><updated>2009-11-30T14:51:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;I've written a lot about this already, but I think one particular point bears repeating.&lt;/P&gt;
&lt;P&gt;As we're getting closer to shipping C# 4.0, I'm seeing a lot of documents, blogs, and so on, attempting to explain what "covariant" means. This is a tricky word to define in a way that is actually meaningful to people who haven't already got degrees in category theory, but it can be done. And I think it's important to avoid defining a word to mean something other than its actual meaning.&lt;/P&gt;
&lt;P&gt;A number of those documents have led with something like:&lt;/P&gt;
&lt;P&gt;"Covariance is the ability to assign an expression of a more specific type to a variable of a less specific type. For example, consider a method M that returns a Giraffe. You can assign the result of M to a variable of type Animal, because Animal is a less specific type that is compatible with Giraffe. Methods in C# are 'covariant' in their return types, which is why when you create a covariant interface, it is indicated with the keyword 'out' -- the returned value comes 'out' of the method."&lt;/P&gt;
&lt;P&gt;But that's &lt;STRONG&gt;not at all&lt;/STRONG&gt; what covariance means. That's describing "assignment compatibility" -- the ability to assign a value of a more specific type to a storage of a compatible, less specific type is called "assignment compatibility" because the two types are compatible for the purposes of verifying legality of assignments.&lt;/P&gt;
&lt;P&gt;So what does covariance mean then?&lt;/P&gt;
&lt;P&gt;First off, we need to work out precisely what the adjective "covariant" applies to. I'm going to get more formal for a bit here, but try to keep it understandable.&lt;/P&gt;
&lt;P&gt;Let's start by not even considering types. Let's think about integers. (And here I am speaking of actual mathematical integers, not of the weird behaviour of 32-bit integers in unchecked contexts.) Specifically, we're going to think about the ≤ relation on integers, the "less than or equal to" relation. (Recall that of course a "relation" is a function which takes two things and returns a bool which indicates whether the given relationship holds or does not hold.)&lt;/P&gt;
&lt;P&gt;Now let's think about a projection on integers. What is a projection? A projection is a function which takes a single integer and returns a new integer. So, for example, z → z + z is a projection; call it D for "double".&amp;nbsp; So are z → 0 - z, N for "negate" and z → z * z, S for "square".&lt;/P&gt;
&lt;P&gt;Now, here's an interesting question. Is it always the case that (x ≤ y) = (D(x) ≤ D(y))?&amp;nbsp; Yes, it is. If x is less than y, then twice x is less than twice y. If x is equal to y then twice x is equal to twice y. And if x is greater than y, then twice x is greater than twice y. The projection D preserves the direction of size.&lt;/P&gt;
&lt;P&gt;What about N? Is it always the case that (x ≤ y) = (N(x) ≤ N(y))?&amp;nbsp; Clearly not. 1 ≤ 2 is true, but -1 ≤ -2 is false. But we notice that the reverse is always true!&amp;nbsp; (x ≤ y) = (N(y) ≤ N(x)). The projection N reverses the direction of size.&lt;/P&gt;
&lt;P&gt;What about S? Is it always the case that (x ≤ y) = (S(x) ≤ S(y))? No. -1 ≤ 0 is true, but S(-1) ≤ S(0) is false. What about the opposite? Is it always the case that (x ≤ y) = (S(y) ≤ S(x)) ? Again, no. 1 ≤ 2 is true, but S(2) ≤ S(1) is false. The projection S does not preserve the direction of size, and nor does it reverse it. &lt;/P&gt;
&lt;P&gt;The projection D is "covariant" -- it preserves the ordering relationship on integers. The projection N is "contravariant". It reverses the ordering relationship on integers. The projection S does neither; it is "invariant".&lt;/P&gt;
&lt;P&gt;Now I hope it is more clear exactly what is covariant or contravariant. The integers themselves are not variant, and the "less than" relationship is not variant. It's &lt;STRONG&gt;the projection&lt;/STRONG&gt; that is covariant or contravariant -- the rule for taking an old integer and making a new one out of it.&lt;/P&gt;
&lt;P&gt;So now lets abandon integers and think about reference types. Instead of the ≤ relation on integers, we have the ≤ relation on reference types. A reference type X is smaller than (or equal to) a reference type Y if a value of type X can be stored in a variable of type Y. That is, if X is "assignment compatible" with Y.&lt;/P&gt;
&lt;P&gt;Now consider a projection from types to types. Say, the projection "T goes to IEnumerable&amp;lt;T&amp;gt;".&amp;nbsp; That is, we have a projection that takes a type, say, Giraffe, and gives you back a new type, IEnumerable&amp;lt;Giraffe&amp;gt;. Is that projection covariant in C# 4?&amp;nbsp; Yes. It preserves the direction of ordering. A Giraffe may be assigned to a variable of type Animal, and therefore an sequence of Giraffes may be assigned to a variable that can hold a sequence of Animals.&lt;/P&gt;
&lt;P&gt;We can think of generic types as "blueprints" that produce constructed types. Let's take the projection that takes a type T and produces IEnumerable&amp;lt;T&amp;gt; and simply call that projection "IEnumerable&amp;lt;T&amp;gt;". We can understand from context when we say "IEnumerable&amp;lt;T&amp;gt; is covariant" what we mean is "the projection which takes a reference type T and produces a reference type IEnumerable&amp;lt;T&amp;gt; is a covariant projection". And since IEnumerable&amp;lt;T&amp;gt; only has one type parameter, it is clear from the context that we mean that the parameter to the projection is T. After all, it is a lot shorter to say "IEnumerable&amp;lt;T&amp;gt; is covariant" than that other mouthful.&lt;/P&gt;
&lt;P&gt;So now we can define covariance, contravariance and invariance. A generic type I&amp;lt;T&amp;gt; is &lt;STRONG&gt;covariant&lt;/STRONG&gt; (in T) if construction with reference type arguments &lt;STRONG&gt;preserves&lt;/STRONG&gt; the direction of assignment compatibility. It is &lt;STRONG&gt;contravariant&lt;/STRONG&gt; (in T) if it &lt;STRONG&gt;reverses&lt;/STRONG&gt; the direction of assignment compatibility. And it is &lt;STRONG&gt;invariant&lt;/STRONG&gt; if it does neither. And by that, we simply are saying in a concise way that the &lt;STRONG&gt;projection&lt;/STRONG&gt; which takes a T and produces I&amp;lt;T&amp;gt; is a covariant/contravariant/invariant projection.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;UPDATE: My close personal friend (and fellow computer geek)&amp;nbsp;Jen notes that in the Twilight series of novels, the so-called "werewolves" (who are not transformed by the full moon and therefore not actually werewolves) maintain their rigid social ordering in both wolf and human form; the projection from human to wolf is covariant in the social-ordering relation. She also notes that in high school, programming language geeks are at the bottom of the social order, but the projection to adulthood catapults them to the top of the social order, and therefore, growing up is contravariant. I am somewhat skeptical of the latter claim; the former, I'll take your word for it. I suppose the question of how social order works amongst teenage werewolves who are computer geeks is a subject for additional research. Thanks Jen!&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923199" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="Rarefied Heights" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Rarefied+Heights/default.aspx" /><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Covariance and Contravariance" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx" /><category term="C# 4.0" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx" /><category term="What's The Difference?" scheme="http://blogs.msdn.com/ericlippert/archive/tags/What_2700_s+The+Difference_3F00_/default.aspx" /></entry><entry><title>The Purpose, Revealed</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/25/the-purpose-revealed.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/25/the-purpose-revealed.aspx</id><published>2009-11-25T17:03:00Z</published><updated>2009-11-25T17:03:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Interestingly enough, no one correctly guessed why I needed code in the compiler to transform a method argument list into a form that batched up the side effecting expressions, stuck their values in variables, and then called the method with the side-effect-free variable references. There certainly were some fascinating ideas in the comments though!&lt;/P&gt;
&lt;P&gt;The reason is quite mundane. We had a bug in the code that performs semantic analysis of calls with named arguments. One of our rules in C# that I've talked about a lot on this blog is that sub-expression evaluation occurs in left-to-right order. If you have a method &lt;SPAN class=code&gt;void&amp;nbsp;M(int&amp;nbsp;x,&amp;nbsp;int&amp;nbsp;y)&amp;nbsp;{} &lt;/SPAN&gt;and then a call site &lt;SPAN class=code&gt;M(y&amp;nbsp;:&amp;nbsp;F(),&amp;nbsp;x&amp;nbsp;:&amp;nbsp;G());&lt;/SPAN&gt; we cannot simply generate the code as though you'd written &lt;SPAN class=code&gt;M(G(),&amp;nbsp;F())&lt;/SPAN&gt;. The side effects of F have to happen before the side effects of G, so we generate code as though you'd said &lt;SPAN class=code&gt;temp1&amp;nbsp;=&amp;nbsp;F(); temp2&amp;nbsp;=&amp;nbsp;G(); M(y&amp;nbsp;:&amp;nbsp;temp1,&amp;nbsp;x&amp;nbsp;:&amp;nbsp;temp2);&lt;/SPAN&gt; and now we can generate the call as &lt;SPAN class=code&gt;M(temp2,&amp;nbsp;temp1);&lt;/SPAN&gt; without worrying about re-ordering a side effect. &lt;/P&gt;
&lt;P&gt;The bug was that the rewriter was not getting the reordering correct if the parameters were ref/out or the arguments were locals without side effects. As I often do when fixing a bug, I reasoned that the initial bug had been caused because the rewriter was under-specified. &lt;/P&gt;
&lt;P&gt;The fix will get into the initial release of C# 4, but the problems that Pavel identified with it -- that certain obscure side effects such as the order in which bad array accesses throw exceptions, or the order in which static class constructors execute, are not correctly preserved by my algorithm, will not be fixed for the initial release. Doing these correctly requires us to be able to generate temporaries of "reference to argument" types, which we've never done before and which our IL generator was not built to handle. Had we discovered the bug much earlier in the cycle, we probably could have applied a more solid fix, but it is too late now. &lt;/P&gt;
&lt;P&gt;Thanks again to Pavel for the great analysis, and thanks to our old friend nikov for reporting the bug in the first place. &lt;/P&gt;
&lt;P&gt;And happy thanksgiving to my readers in the United States! As I do every year, I'm roasting a turkey to feed fourteen people. I highly recommend the "brine the bird then&amp;nbsp;roast it upside-down" method described in The Joy Of Cooking. It's worked perfectly&amp;nbsp;for me for the last ten years straight.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9928668" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Code Generation" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx" /><category term="Software development methodology" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx" /><category term="C# 4.0" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="named parameters" scheme="http://blogs.msdn.com/ericlippert/archive/tags/named+parameters/default.aspx" /></entry><entry><title>Always write a spec, Part Two</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/23/always-write-a-spec-part-two.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/23/always-write-a-spec-part-two.aspx</id><published>2009-11-23T15:01:00Z</published><updated>2009-11-23T15:01:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Upon submitting that specification for review, even before seeing my code, Chris found a bug and an omission.&lt;/P&gt;
&lt;P&gt;The omission is that I neglected to say what happens when the ref variable is an index into a fixed-size array buffer. As it turns out, that case is also rewritten as a pointer dereference by the time we get to this point in the code, so missing that case turned out to not be a big deal.&lt;/P&gt;
&lt;P&gt;The bug is that this line is wrong:&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;if x is ref/out instance.field then&amp;nbsp;add var temp=instance&amp;nbsp;to&amp;nbsp;L and ref/out temp.field to A2. &lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;because it does not meet the stated goal of the method,&amp;nbsp;namely, to&amp;nbsp;produce the same results after the transformation:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;struct S { public int q; }&lt;BR&gt;static void M(ref int r) { r = r + 1; }&lt;BR&gt;static int Zero() { Console.WriteLine("hello!"); return 0; }&lt;BR&gt;...&lt;BR&gt;S[] arr = new[] { new S() };&lt;BR&gt;M(ref arr[Zero()].q);&lt;BR&gt;Console.WriteLine(arr[0].q); // 1&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Here we have a variable expression of the form instance.field which has a side effect; it prints "Hello". So according to the spec, we rewrite that as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;S&amp;nbsp;temp = arr[Zero()];&lt;BR&gt;M(ref temp.q);&lt;BR&gt;Console.WriteLine(arr[0].q); // 0 !&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Once more, mutable value types are revealed to be pure concentrated evil. We just mutated temp.q, which is a &lt;EM&gt;copy&lt;/EM&gt; of arr[0].&lt;/P&gt;
&lt;P&gt;The interesting thing here is that Chris found the bug by &lt;STRONG&gt;reading the spec&lt;/STRONG&gt; and thinking about whether I'd missed any interesting cases. Bugs are always cheaper to fix the earlier you find them; a bug you fix as a result of reading the spec is a bug that you don't have to pay QA to find, it's a bug that your customers never see, it's a bug that never causes a backwards-compatibility breaking change, and so on.&lt;/P&gt;
&lt;P&gt;I thought hard about this and realized that the painful case only happens when we have ref/out instance.field with a side effect and &lt;STRONG&gt;instance is a variable of value type&lt;/STRONG&gt;. That's the missing case. Furthermore, we can solve this by recursing!&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;UL&gt;
&lt;LI&gt;if x is ref/out instance.field and&amp;nbsp;instance is&amp;nbsp;a variable of value type, then recurse. Compute T("ref instance"), as if we were invoking a method that takes a single parameter of this ref type. That will give us a resulting declaration list, which we merge onto the end of L, and a resulting argument list with one element on it, r. Add "ref r.field" to A2.&lt;/LI&gt;
&lt;LI&gt;if x is a ref/out instance.field but instance is not a variable of value type, then generate var temp=instance on L, &amp;nbsp;ref temp.field on A2.&lt;/LI&gt;&lt;/UL&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;So if we have, say, &lt;SPAN class=code&gt;M(ref arr[index].q)&lt;/SPAN&gt;, that ultimately is generated as &lt;SPAN class=code&gt;var t1 = arr, var t2 = index, M(ref t1[t2].q)&lt;/SPAN&gt;, which is correct.&lt;/P&gt;
&lt;P&gt;I fixed up my implementation, wrote some test cases to test the spec, and sent it off to testing for further analysis.&lt;/P&gt;
&lt;P&gt;There's &lt;EM&gt;still&lt;/EM&gt; a bug in this spec, which our tester David found during his analysis of my spec plus proposed implementation. Hint: the problem has nothing to do with ref/out semantics; it's a more fundamental error in reasoning.&lt;/P&gt;
&lt;P&gt;Feel free to pause and reflect for a moment if you want a chance to figure it out for yourself.&lt;/P&gt;
&lt;P&gt;...&lt;/P&gt;
&lt;P&gt;The error is in the default case:&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;First, if x has no side effects, then simply keep x in the appropriate place in A2.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Whether x has side effects or not is completely irrelevant; what is relevant is whether the computation of x depends on the order of every other side effect!&lt;/P&gt;
&lt;P&gt;For example, our spec would have that &lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int k = 0;&lt;BR&gt;M( k, arr[k=1] );&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;is the same as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int k = 0;&lt;BR&gt;var t1&amp;nbsp;= arr;&lt;BR&gt;var&amp;nbsp;t2 = (k = 1);&lt;BR&gt;M(k,&amp;nbsp;t1[t2]);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;which is clearly not correct; the first argument&amp;nbsp;is supposed to be zero, not one. The fact that the first argument has no side effects is irrelevant; it depends on the second argument's side effect taking effect &lt;EM&gt;after&lt;/EM&gt; the first argument's &lt;EM&gt;value&lt;/EM&gt; is computed.&lt;/P&gt;
&lt;P&gt;We have to fix up the spec (and implementation) to say that if the argument corresponds to a &lt;EM&gt;value&lt;/EM&gt; parameter, you &lt;EM&gt;always&lt;/EM&gt; save away the value in a temporary, regardless of whether it has side effects or not. If it corresponds to, say, a ref parameter, and the argument is a ref to a local then we can still simply generate the ref to the local normally; regardless of whether the contents of the local change, the managed address of the local is always the same, and computing the address of a local causes no side effects.&lt;/P&gt;
&lt;P&gt;I note that we could also make an exception in the case that the value is, say, a compile-time constant. Clearly the computation of its value does not have any dependency on the ordering of other side effects. But for the sake of not further complexifying my spec and implementation, I glossed over this detail. The optimizer will probably take care of it.&lt;/P&gt;
&lt;P&gt;Commenter Pavel Minaev found several more corner cases&amp;nbsp;that none of us found. The big one is that we should be clear about what happens with multidimensional arrays, and in fact, I had a bug in my implementation for multidimensional arrays, so thanks Pavel! He also found some obscure ones. One is that accessing a static field does have a side effect; if this is the first access to the class then&amp;nbsp;that causes the static class constructor to run, which could have observable side effects.&amp;nbsp;Another is that the exact semantics of when bad arguments cause exceptions is slightly changed by this transformation.&lt;/P&gt;
&lt;P&gt;At this point I now believe that I have a correct specification of my function T (modulo Pavel's weird issues, which I'm still mulling over. But those are bizarre corner cases that might require some language spec work to sort out.) Since the implementation is a straightforward transformation of the specification into C++, I also believe I have a correct implementation. I've written test cases that verify every case in the spec, and handed it off to testing to look for practical cases I missed.&lt;/P&gt;
&lt;P&gt;Anyone see any other problems with this spec? Anyone?&lt;/P&gt;
&lt;P&gt;And anyone have any guesses as to why I needed this function implemented?&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9921574" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Code Quality" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx" /><category term="Software development methodology" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx" /><category term="Value Types" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx" /></entry><entry><title>Always write a spec, part one</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/19/always-write-a-spec-part-one.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/19/always-write-a-spec-part-one.aspx</id><published>2009-11-19T14:45:00Z</published><updated>2009-11-19T14:45:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Joel had a great series of articles many years ago about &lt;A href="http://www.joelonsoftware.com/articles/fog0000000036.html" mce_href="http://www.joelonsoftware.com/articles/fog0000000036.html"&gt;the benefits of writing functional specifications&lt;/A&gt;, that is, specifications of how the product looks to its users. I want to talk a bit about technical specifications, that is, a specification of how something actually works behind the scenes. A while back, I described how I wrote a seemingly-trivial piece of code by &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/06/01/bug-psychology.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/06/01/bug-psychology.aspx"&gt;first writing the technical spec, and then writing the code to exactly implement the spec&lt;/A&gt;, and the test cases to test each statement of the spec. I use this technique frequently; it almost always saves me time and effort. If you don't write a spec first, it's very easy to get bogged down in a morass of bugs, and hard to know when you're actually done writing the code.&lt;/P&gt;
&lt;P&gt;Here's an example of another seemingly-trivial function that &lt;A href="http://stackoverflow.com/questions/921180/c-round-up/926806#926806" mce_href="http://stackoverflow.com/questions/921180/c-round-up/926806#926806"&gt;smart people gave a good half-dozen completely wrong answers to because they didn't write a spec&lt;/A&gt;. Notice how once I state what the spec is, the code follows very naturally.&lt;/P&gt;
&lt;P&gt;I thought I might go through a recent example of a slightly less trivial problem. I needed a function in the compiler which could take a valid list of arguments A1 to an applicable method M, and give me back two lists. The first result list is a list of &lt;EM&gt;local variable declarations&lt;/EM&gt;, L, the second, another argument list, A2. Here's the kicker: evaluating each member of A2 &lt;EM&gt;must have no side effects&lt;/EM&gt;. And, the combination of executing L followed by M(A2) must give &lt;EM&gt;exactly the same results&lt;/EM&gt; as executing M(A1). (I also knew that the members of A1 had already had all the conversions generated to make them match the types of M's parameter list, and so on. Overload resolution was completely done at this point.)&lt;/P&gt;
&lt;P&gt;Why I needed such a function is not particularly important; perhaps you can speculate as to why I needed it.&lt;/P&gt;
&lt;P&gt;So I started writing a spec, starting with the description above: the function T takes a valid list... blah blah blah.&lt;/P&gt;
&lt;P&gt;That's not enough of a spec to actually write code. &lt;/P&gt;
&lt;P&gt;I realized that some expressions in A1 might have side effects, and some might not. If an expression had side effects, then I could declare a temp local, execute the side effects, assign the result to the local, and then use the local as the expression in the same place in A2.&lt;/P&gt;
&lt;P&gt;Super. Now I can write more sentences in my spec.&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;For each argument x in A1, we potentially generate a temporary value as follows: First, if x has no side effects, then simply keep x in the appropriate place in A2. Otherwise, if x does have side effects, then generate a temporary variable declaration in L, var temp = x. Then put an expression that evaluates the temporary variable in the appropriate place in A2.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Then I thought "can I correctly implement this spec?"&lt;/P&gt;
&lt;P&gt;I started thinking about the possible cases for the input, A1. The members of A1 could be passed by value, out, or ref; I already knew they were correct, since the particular method M was an applicable method of argument list A1. In this particular point in the compilation process, there was no need to worry about whether there were "params" arguments, whether there were missing arguments with default values, and so on; that had already been taken care of. I also noted that whether they were "ref" or "out" was irrelevant; ref and out are the same thing behind the scenes. As far as the compiler is concerned, the only difference between them is that the definite assignment rules are different for each.&amp;nbsp;So we had two cases for each argument: it's being passed by value, or by ref/out. &lt;/P&gt;
&lt;P&gt;If it's being passed by ref/out, then what we actually do is we pass&amp;nbsp;the managed address of&amp;nbsp;a variable to the method. In M(ref int x), the type of x is actually a special type int&amp;amp;, "managed reference to variable of type int", which is not a legal type in C#. That's why we hide it from you by requiring a goofy "ref" syntax any time you want to talk about a managed reference to a variable.&lt;/P&gt;
&lt;P&gt;Unfortunately, our IL generation pass was written with the assumption that all local variables are never of these magic managed-reference-to-variable types. I was then faced with a choice. Either come up with a technique for working with this limitation, or rewrite the most complicated code in the IL gen to support this scenario. (The code which figures out how to deal with managed references is quite complex.) I decided to opt for the former strategy. Which meant more spec work, since our spec now doesn't handle these cases!&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;For each argument x in A1, we potentially generate a temporary value as follows: &lt;/P&gt;
&lt;P&gt;First, if x has no side effects, then simply keep x in the appropriate place in A2. &lt;/P&gt;
&lt;P&gt;Otherwise, if x does have side effects &lt;STRONG&gt;and corresponds to a value parameter&lt;/STRONG&gt;, then generate ... etc.&lt;/P&gt;
&lt;P&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, &lt;STRONG&gt;then a miracle happens&lt;/STRONG&gt;.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Clearly that last bit needed some work.&lt;/P&gt;
&lt;P&gt;So I wrote down all the possible cases I could think of. Clearly x has to be a variable if its type is "reference to variable", so that makes for a small number of cases:&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, then the possible cases are:&lt;/P&gt;
&lt;P&gt;* x is a local variable&lt;BR&gt;* x is a value parameter&lt;BR&gt;* x is an out parameter&lt;BR&gt;* x is a ref parameter&lt;BR&gt;* x is a field of an instance&lt;BR&gt;* x is a static field&lt;BR&gt;* x is an array element&lt;BR&gt;* x is a pointer dereferenced with *&lt;BR&gt;* x is a pointer dereferenced with [ ]&lt;/P&gt;
&lt;P&gt;and for each, a miracle happens.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;Again, clearly this is not good enough. I re-examined my list to see if I could eliminate any of these cases. Locals, parameters and&amp;nbsp;static fields never have side effects, so we can eliminate them.&lt;/P&gt;
&lt;P&gt;Also, at this point in our analysis, I knew that pointer dereferences of the form "pointer[index]" had already been rewritten into the form "*(pointer + index)", which meant that in practice, we would never actually hit that last case in this algorithm; the second-last case would take care of both.&lt;/P&gt;
&lt;HR&gt;

&lt;DIV class=spec&gt;
&lt;P&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, then the possible cases are:&lt;/P&gt;
&lt;P&gt;* x is a field of an instance&lt;BR&gt;* x is an array element&lt;BR&gt;* x is a pointer dereferenced with *&lt;BR&gt;&lt;BR&gt;and for each, a miracle happens.&lt;/P&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;I then started to think of what side effects could happen for each.&amp;nbsp;We could have "ref instance.field", "ref array[index]", or "ref *pointer", and&amp;nbsp;"instance", "array", "index" and "pointer" can all be expressions that have a&amp;nbsp;side effect. ("field" cannot, it merely names a field.) So now we can use the same specification as before:&lt;/P&gt;
&lt;HR&gt;

&lt;P class=spec&gt;Otherwise, if x does have side effects and corresponds to a ref/out parameter, then the possible cases are:&lt;/P&gt;
&lt;DIV class=spec&gt;
&lt;UL&gt;
&lt;LI&gt;x is ref/out instance.field: in this case,&amp;nbsp;add var temp=instance&amp;nbsp;to&amp;nbsp;L and ref/out temp.field to A2.&lt;/LI&gt;
&lt;LI&gt;x is ref/out array[index]: in this case, add var t1 = array and&amp;nbsp;var t2 = index to L and ref/out t1[t2] to A2.&lt;/LI&gt;
&lt;LI&gt;x is ref/out *pointer: in this case, add var temp = pointer to L and ref/out *temp to A2.&lt;/LI&gt;&lt;/UL&gt;&lt;/DIV&gt;
&lt;HR&gt;

&lt;P&gt;And now we have something I can implement. So I sent this proposed spec around for review, while I started plugging away at the implementation.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;This spec is wrong.&lt;/STRONG&gt; Can you spot the&amp;nbsp;bugs in my implementation&amp;nbsp;that my coworkers found by reading my spec?&lt;/P&gt;
&lt;P&gt;Next time, the thrilling conclusion.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9921545" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Puzzles" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx" /><category term="Code Quality" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Code+Quality/default.aspx" /><category term="Software development methodology" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx" /></entry><entry><title>Closing over the loop variable, part two</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/16/closing-over-the-loop-variable-part-two.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/16/closing-over-the-loop-variable-part-two.aspx</id><published>2009-11-16T16:18:00Z</published><updated>2009-11-16T16:18:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Thanks to everyone who left thoughtful and insightful comments on last week's post.&lt;/P&gt;
&lt;P&gt;More countries&amp;nbsp;really ought to implement Instant Runoff Voting; it would certainly appeal to the geek crowd. Many people left complex opinions of the form "I'd prefer to make the change, but if you can't do that then make it a warning". Or "don't make the change, do make it a warning", and so on.&amp;nbsp;But what I can deduce from reading the comments is that there is a general lack of consensus on what the right thing to do here is. In fact, I just did a quick tally:&lt;/P&gt;
&lt;P&gt;Commenters who expressed support for a warning: 26&lt;BR&gt;Commenters who expressed the sentiment "it's better to not make the change": 24&lt;BR&gt;Commenters who expressed the sentiment "it's better to make the change": 25&lt;/P&gt;
&lt;P&gt;Wow. I guess we'll flip a coin. :-)&amp;nbsp;&amp;nbsp;&amp;nbsp; (*)&lt;/P&gt;
&lt;P&gt;Four people suggested to actually make it an error to do this. That's a pretty big breaking change, particularly since we would be breaking not just "already broken" code, but plenty of code that works perfectly well today -- see below. That's not likely to happen.&lt;/P&gt;
&lt;P&gt;People also left a number of interesting suggestions. I thought I'd discuss some of those a little bit.&lt;/P&gt;
&lt;P&gt;First off, I want to emphasize that what we're attempting to address here is the problem that &lt;STRONG&gt;the language encourages people to write code that has different semantics than they think it has&lt;/STRONG&gt;. The problem is NOT that the language has no way to express the desired semantics; clearly it does. Just introduce a new variable explicitly into the loop.&lt;/P&gt;
&lt;P&gt;A number of suggestions were for ways that the language could more elegantly express that notion. Some of the suggestions:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var x in c) &lt;STRONG&gt;inner&lt;/STRONG&gt; &lt;BR&gt;&lt;STRONG&gt;foreachnew&lt;/STRONG&gt;(var x in c)&lt;BR&gt;foreach(&lt;STRONG&gt;new&lt;/STRONG&gt; var x in c)&lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;from&lt;/STRONG&gt; c) &lt;BR&gt;foreach(var x&amp;nbsp;&lt;STRONG&gt;inside&lt;/STRONG&gt; c) &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Though we could do any of those, none of them by themselves solve the problem at hand. Today, you have to know to use a particular pattern with foreach to get the semantics you want: declare a variable inside the loop. With one of these changes, you still have to know to use a particular keyword to get the semantics you want, and it is still easy to accidentally do the wrong thing. &lt;/P&gt;
&lt;P&gt;Furthermore,&amp;nbsp;a change so small and so targetted at such a narrow scenario probably does not provide enough benefit to justify the large cost of creating a new syntax, particularly one which is still easily confused with an existing syntax.&lt;/P&gt;
&lt;P&gt;C++ luminary Herb Sutter happened to be in town and was kind enough to stop by my office to describe to me how they are solving a related problem in C++. Apparently the next version of the C++ standard will include lambdas, and they're doing this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&lt;EM&gt;[q, &amp;amp;r]&lt;/EM&gt; &lt;STRONG&gt;(int x) -&amp;gt; int&lt;/STRONG&gt; { return M(x, q, r); }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This means that the lambda captures outer variable q by value, captures r by reference, takes an int and returns an int. Whether the lambda captures values or references is controllable! An interesting approach but one that doesn't immediately solve our problem here; we cannot make lambdas capture by value by default without a huge breaking change. Capturing by value would have to require new syntax, and then we're in the same boat again: the user has to know to use the new syntax when in a foreach loop.&lt;/P&gt;
&lt;P&gt;A number of people also asked what the down sides of adding a warning are. The down side is that &lt;STRONG&gt;a warning which warns about correct behaviour is a very bad warning&lt;/STRONG&gt;; it makes people change working code, and frequently they break working code in order to eliminate a warning that shouldn't have been present in the first place. Consider:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var insect in insects)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var query = frogs.Where(frog=&amp;gt;frog.Eats(insect));&lt;BR&gt;&amp;nbsp; Console.WriteLine("{0} is eaten by {1} frogs.", insect, query.Count());&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This makes a lambda closed over insect; the lambda never escapes the loop, so there's no problem here. But the compiler doesn't know that. The compiler sees that the lambda is being passed to a method called Where, and Where is allowed to do anything with that delegate, including storing it away to be called later. Which is exactly what Where does! Where stores away the lambda into a monad that represents the execution of the query. The fact that the &lt;STRONG&gt;query object doesn't survive the loop&lt;/STRONG&gt; is what keeps this safe. But how is the compiler supposed to suss out that tortuous chain of reasoning? We'd have to give a warning for this case, even though it is perfectly safe. &lt;/P&gt;
&lt;P&gt;It gets worse. A lot of people are required by their organizations to compile with "warnings are errors" turned on. Therefore, any time we introduce a new warning for a pattern that is often actually safe and frequently used, we are effectively causing an enormous breaking change. A vaccine which kills more healthy people than the disease would have is probably not a good bet. (**)&lt;/P&gt;
&lt;P&gt;This is not to say that a warning is a bad idea, but that it is not the obvious slam dunk good idea that it initially appears to be.&lt;/P&gt;
&lt;P&gt;A number of people suggested that the problem was in the training of the developers, not in the design of the language. I disagree. Obviously modern languages are complex tools that require training to use, but we are working hard to make a language where people's natural intuitions about how things work lead them to write correct code. I have myself made this error a number of times, usually in the form of writing code like the code above, and then refactoring it in such a manner that suddenly some part of it escapes the loop and the bug is introduced. It is very easy to make this mistake, even for experienced developers who thoroughly understand closure semantics. That's a flaw in the design of the language. &lt;/P&gt;
&lt;P&gt;And finally, a number of people made suggestions of the form "make it a warning in C# 4, and an error in C# 5", or some such thing. FYI, C# 4 is DONE. We are only making a few last-minute "user is electrocuted"-grade bug fixes, mostly based on your excellent feedback from the betas. (If you have bug reports from the beta, please keep sending them, but odds are good they won't get fixed for the initial release.) We are certainly not capable of introducing any sort of major design change or new feature at this point. And we try to not introduce semantic changes or new features in service packs. We're going to have to live with this problem for at least another cycle, unfortunately.&lt;/P&gt;
&lt;P&gt;********&lt;/P&gt;
&lt;P&gt;(*) Mr. Smiley Face indicates that Eric is indulging in humourous japery.&lt;/P&gt;
&lt;P&gt;(**) I wish to emphasize that I am 100% in favour of vaccinations for deadly infectious&amp;nbsp;diseases, &lt;EM&gt;even vaccines that are potentially dangerous&lt;/EM&gt;. The number of people made ill or killed by the smallpox vaccine was tiny compared to the number of people who did not contract this deadly, contagious (and now effectively extinct)&amp;nbsp;disease as a result of mass vaccination. I am a strong supporter of vaccine research. I'm just making an analogy here people.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9923025" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Breaking Changes" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx" /><category term="Lambda Expressions" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx" /><category term="foreach" scheme="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx" /><category term="closures" scheme="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx" /><category term="coin flipping" scheme="http://blogs.msdn.com/ericlippert/archive/tags/coin+flipping/default.aspx" /></entry><entry><title>Closing over the loop variable considered harmful</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx</id><published>2009-11-12T14:50:00Z</published><updated>2009-11-12T14:50:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;I don't know why I haven't blogged about this one before; this is the single most common incorrect bug report we get. That is, someone thinks they have found a bug&amp;nbsp;in the compiler, but in fact the compiler is correct and their code is wrong. That's a terrible situation for everyone; we very much wish to design a language which does not have "gotcha" features like this. &lt;/P&gt;
&lt;P&gt;But I'm getting ahead of myself. What's the output of this fragment?&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;var&amp;nbsp;values = new List&amp;lt;int&amp;gt;() { 100, 110, 120 };&lt;BR&gt;var&amp;nbsp;funcs = new List&amp;lt;Func&amp;lt;int&amp;gt;&amp;gt;();&lt;BR&gt;foreach(var v in values) &lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v );&lt;BR&gt;foreach(var f&amp;nbsp;in funcs) &lt;BR&gt;&amp;nbsp; Console.WriteLine(f());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Most people expect it to be 100 / 110 / 120.&amp;nbsp; It is in fact 120 / 120 / 120. Why?&lt;/P&gt;
&lt;P&gt;Because &lt;SPAN class=code&gt;()=&amp;gt;v&lt;/SPAN&gt; means "return &lt;STRONG&gt;the current value of variable v&lt;/STRONG&gt;", not "return the value v was back when the delegate was created". &lt;STRONG&gt;Closures close over variables, not over values.&lt;/STRONG&gt; And when the methods run, clearly the last value that was assigned to v was 120, so it still has that value.&lt;/P&gt;
&lt;P&gt;This is very confusing. The correct way to write the code is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;foreach(var v in values) &lt;BR&gt;{&lt;BR&gt;&amp;nbsp; var v2 = v;&lt;BR&gt;&amp;nbsp; funcs.Add( ()=&amp;gt;v2 );&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Now what happens? Every time we re-start the loop body, we logically create a fresh new variable v2. Each closure is closed over a different v2, which is only assigned to once, so it always keeps the correct value. &lt;/P&gt;
&lt;P&gt;Basically, the problem arises because we specify that the foreach loop is a syntactic sugar for&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;int&amp;gt; e = ((IEnumerable&amp;lt;int&amp;gt;)values).GetEnumerator();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // OUTSIDE THE ACTUAL LOOP&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; finally&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e != null) ((IDisposable)e).Dispose();&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR minmax_bound="true"&gt;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If we specified that the expansion was&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m; // INSIDE&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m = (int)(int)e.Current;&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;funcs.Add(()=&amp;gt;m);&lt;BR minmax_bound="true"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then the code would behave as expected.&lt;/P&gt;
&lt;P&gt;It's compelling to consider fixing this for a hypothetical future version of C#, and I'd like to hear your feedback on whether we should do so or not. The reasons FOR making the change are clear; this is a big confusing "gotcha" that real people constantly run into, and LINQ, unfortunately, only makes it worse, because it is likely to increase the number of times&amp;nbsp;a customer is going to use a closure in a loop. Also, it seems reasonable that the user of the&amp;nbsp;foreach loop&amp;nbsp;might&amp;nbsp;think of&amp;nbsp;there being&amp;nbsp;a "fresh" loop variable every time, not just a fresh value in the same old variable. Since the foreach loop variable is not mutable by user code, this reinforces the idea that it is a succession of values, one per loop iteration, and not "really" the same variable over and over again. And finally, the change has no effect whatsoever on non-closure semantics. (In fact, in C# 1 the spec was not clear about whether the loop variable went inside or outside, since in a world without closures, it makes no difference.)&lt;/P&gt;
&lt;P&gt;But that said, there are some very good reasons for not making this change.&lt;/P&gt;
&lt;P&gt;The first reason is that obviously this would be a breaking change, and we hates them, my precious. Any developers who depend on this feature, who require the closed-over variable to contain the last value of the loop variable, would be broken. I can only hope that the number of such people is vanishingly small; this is a strange thing to depend on. Most of the time, people do not expect or depend on this behaviour.&lt;/P&gt;
&lt;P&gt;Second, it makes the foreach syntax lexically inconsistent. Consider &lt;SPAN class=code&gt;foreach(int x in M())&lt;/SPAN&gt; The header of the loop has two parts, a declaration &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; and a collection expression, &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. The &lt;SPAN class=code&gt;int x&lt;/SPAN&gt; is to the left of the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt;. Clearly the &lt;SPAN class=code&gt;M()&lt;/SPAN&gt; is not inside the body of the loop; that thing only executes once, before the loop starts. So &lt;EM&gt;why should something to the collection expression's left be inside the loop&lt;/EM&gt;? This seems inconsistent with our general rule that stuff to the left logically "happens before" stuff to the right. The declaration is lexically NOT in the body of the loop, so why should we treat it as though it were?&lt;/P&gt;
&lt;P&gt;Third, it would make the "foreach" semantics inconsistent with "for" semantics. We have this same problem in "for" blocks, but "for" blocks are much looser about what "the loop variable" is; there can be more than one variable declared in the for loop header, it can be incremented in odd ways, and it seems implausible that people would consider each iteration of the "for" loop to contain a fresh crop of variables. When you say &lt;SPAN class=code&gt;for(int i; i &amp;lt; 10; i += 1)&lt;/SPAN&gt; it seems dead obvious that the "i += 1" means "increment the loop variable" and that there is one loop variable for the whole loop, not a new fresh variable "i" every time through! We certainly would not make this proposed change apply to "for" loops.&lt;/P&gt;
&lt;P&gt;And fourth, though this is a nasty gotcha, there is an easy workaround, and tools like ReSharper detect this pattern and suggest how to fix it. We could take a page from that playbook and simply&amp;nbsp;issue a compiler warning on this pattern. (Though adding new warnings brings up a whole raft of issues of&amp;nbsp;its own, which I might get into in another post.)&amp;nbsp;Though this is vexing, it really doesn't bite that many people that hard, and it's not a big deal to fix, so why go to the trouble and expense of taking a breaking change for something with an easy fix?&lt;/P&gt;
&lt;P&gt;Design is, of course, the art of compromise in the face of many competing principles. "Eliminate gotchas" in this case directly opposes other principles like "no breaking changes", and "be consistent with other language features". Any thoughts you have on pros or cons of us taking this breaking change in a hypothetical future version of C# would be greatly appreciated. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9918689" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Breaking Changes" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx" /><category term="Lambda Expressions" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="foreach" scheme="http://blogs.msdn.com/ericlippert/archive/tags/foreach/default.aspx" /><category term="closures" scheme="http://blogs.msdn.com/ericlippert/archive/tags/closures/default.aspx" /></entry><entry><title>Three Umpires</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/09/three-umpires.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/09/three-umpires.aspx</id><published>2009-11-09T15:01:00Z</published><updated>2009-11-09T15:01:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Three baseball umpires are having lunch together. The first umpire says "Well, a lot of them are balls, and a lot of them are strikes, but I always calls 'em as I sees 'em."&lt;/P&gt;
&lt;P&gt;The second umpire says "Hmph. I calls 'em as they &lt;EM&gt;are&lt;/EM&gt;."&lt;/P&gt;
&lt;P&gt;The third umpire slowly looks at his two colleagues and declares "They ain't &lt;EM&gt;nothin' &lt;/EM&gt;until I calls 'em."&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;Those of you unfamiliar with the bizarre rules of baseball might need a brief primer. Suppose the pitcher throws a pitch and the batter swings and misses. &lt;A class="" href="http://www.amazon.com/gp/recsradio/radio/B000002MSU/ref=pd_krex_dp_001_006/176-2812138-0508753?ie=UTF8&amp;amp;track=006&amp;amp;disc=001" mce_href="http://www.amazon.com/gp/recsradio/radio/B000002MSU/ref=pd_krex_dp_001_006/176-2812138-0508753?ie=UTF8&amp;amp;track=006&amp;amp;disc=001"&gt;Such a failure to strike the ball is, bizarrely enough,&amp;nbsp;called a "strike"&lt;/A&gt;, and counts against the batter;&amp;nbsp;three strikes and the batter is out.&amp;nbsp;But what if the batter fails to swing at all? If the umpire decides that the pitch was "inside the &lt;A class="" href="http://en.wikipedia.org/wiki/Strike_zone" mce_href="http://en.wikipedia.org/wiki/Strike_zone"&gt;strike zone&lt;/A&gt;" then the pitch counts as a strike against the batter. If the pitch was outside the strike zone then the pitch counts as a "ball" (another bizarre and confusing name; obviously the object pitched&amp;nbsp;is also called a ball). If the pitcher pitches four "balls" before the batter accumulates three "strikes" then the batter gets to "walk" to first base for free. (At least the walk is sensibly named.)&lt;/P&gt;
&lt;P&gt;Formally, the strike zone is reasonably well-defined by the rules (though as the Wikipedia article linked to above indicates, there are some subtle points left out of the definition.) But the formal definition is actually irrelevant; the rules of baseball also state that &lt;EM&gt;a strike is any pitch that the umpire says is a strike&lt;/EM&gt;. Umpires are given wide lattitude to declare what is a strike, and there are no appeals allowed.&lt;/P&gt;
&lt;P&gt;And hence the fundamental disagreement between&amp;nbsp;the three umpires. The first umpire believes that&amp;nbsp;whether a pitch was in the strike zone or not is a &lt;EM&gt;fact&lt;/EM&gt; about an objective reality, and that the call&amp;nbsp;is a sometimes-imperfect subjective&amp;nbsp;judgment about that reality. The second umpire seems to be basically agreeing with the objective, materialist stance of the first umpire, and simply&amp;nbsp;bragging about having 100% accuracy in judgment. The third umpire's position is radically different from the first two: that the rules of baseball say that &lt;EM&gt;regardless &lt;/EM&gt;of the objective reality of the path of the baseball, what &lt;EM&gt;makes&lt;/EM&gt; a pitch into a ball or a strike &lt;EM&gt;is the umpire's call&lt;/EM&gt;, no more, no less.&lt;/P&gt;
&lt;P&gt;I think about the three umpires a lot. The C# language has a clear and mostly unambiguous definition of "the strike zone"; the specification should in theory allow us to classify &lt;EM&gt;any&lt;/EM&gt; finite set of finite strings of text into either "a legal C# program" or "not a legal C# program". As a &lt;EM&gt;spec author&lt;/EM&gt;, I take the third umpire's position: what the spec says is the definition of what is legal, end of story. But as an all-too&amp;nbsp;fallible&amp;nbsp;&lt;EM&gt;compiler writer&lt;/EM&gt;, I take the first umpire's position: the compiler calls 'em as it sees 'em. Sometimes an illegal program accidentally (or deliberately; we implement a small number of extensions to the formal C# language) makes it through the compiler. And sometimes a legal program is incorrectly flagged as an error, or cannot be successfully compiled because it causes the compiler to run out of stack space or some other resource. (Also, though I believe that the compiler always in theory terminates, there are ways to build short C# programs that take exponentially long to analyze, making the compiler a sometimes&amp;nbsp;&lt;EM&gt;impractical&lt;/EM&gt; tool for deciding correctness.) But we calls 'em as we sees 'em, and if we get it wrong, then that's a bug.&lt;/P&gt;
&lt;P&gt;But as a practical matter for our customers, the compiler is more like the third umpire: the arbiter of correctness, with no appeal. And of course I haven't even begun to consider the runtime aspects of correctness! Not only should the compiler decide what programs are legal, it should also generate correct code for every legal program. And again, the code generator plus the CLR's verifier and jitter&amp;nbsp;act like our third umpire; the &lt;EM&gt;de facto&lt;/EM&gt; arbiter of what "the right behaviour" actually is.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9917417" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="baseball" scheme="http://blogs.msdn.com/ericlippert/archive/tags/baseball/default.aspx" /></entry><entry><title>Simple names are not so simple, Part Two, plus, volcanoes and fried foods</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/05/simple-names-are-not-so-simple-part-two.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/05/simple-names-are-not-so-simple-part-two.aspx</id><published>2009-11-05T14:52:00Z</published><updated>2009-11-05T14:52:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;I've returned from a brief&amp;nbsp;vacation, visiting friends on the island of Maui. I'd never been to that part of the world before. Turns out, it's a small island in the middle of the Pacific&amp;nbsp;Ocean, entirely made out of volcanoes.&amp;nbsp;Weird!&amp;nbsp;But delightful.&lt;/P&gt;
&lt;P&gt;The most impressive thing about the Hawaiian Islands for me was just how obvious were --&amp;nbsp;even to my completely untrained eyes&amp;nbsp;-- the geomechanical and fluvial processes which shaped the landscape. The mountains and craters and river valleys and red sand beaches and easily-fractured rocks were very different from the (also somewhat volcanic) much older mountainous landscape I've lived in for the past decade.&lt;/P&gt;
&lt;P&gt;Also quite amusing to me was learning to read and pronounce Hawaiian place names. It is all very logical once you know the system; before long I could easily&amp;nbsp;pronounce signs like WAINAPANAPA STATE PARK -- wa-ee-napa-napa&amp;nbsp;--&amp;nbsp;or PUUNENE AVENUE --&amp;nbsp;pu-oo-nay-nay&amp;nbsp;-- or MAILIBEHANAMONOTANA STREET&amp;nbsp;-- "Miley-Stewart-is-really-Hannah-Montana".&lt;/P&gt;
&lt;P&gt;Many thanks to K and R and D for putting me and Leah up for a week; if you're going to Hawai'i and can stay with locals, I highly recommend it, particularly if they are awesome people. Everyone in Maui was awesome, with the exception of the rangers at (stunningly beautiful, even for Maui) Wa'inapanapa State Park, who are apparently consistently grumpy. As one Hawaiian, himself in the camping sector of the economy put it to me, "They do not have&lt;EM&gt; the big aloha&lt;/EM&gt;".&lt;/P&gt;
&lt;P&gt;The most &lt;EM&gt;amusing&lt;/EM&gt; encounter was on the Hana Highway. There are numerous little stops along the way, where someone has erected a hut or parked a trailer and is selling coconuts, smoothies, banana bread, and so on.&amp;nbsp;Hand-lettered signs, stunning natural beauty, middle of nowhere, you get the picture I'm sure. At one of the larger such stops there was a young fellow, probably in his late twenties, serving a variety of fried foods. It was&amp;nbsp;mostly traditional American-style Chinese food, but also he had french fries, fish'n'chips, and so on. He was clearly not a native speaker of English, but spoke understandably with a strong accent. We were waiting behind a middled-aged woman with a typically&amp;nbsp;midwestern American accent. Their conversation went something like this:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Her:&lt;/STRONG&gt; I'm not very hungry, can I just get the fish without the chips?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Him, not quite following her:&lt;/STRONG&gt; Half order?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Her, louder&lt;/STRONG&gt;: How much without the fries?&lt;/P&gt;
&lt;P&gt;This went back and forth for some time, both sides becoming increasingly frustrated by the communication breakdown, until:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Her, even&amp;nbsp;louder&lt;/STRONG&gt;: Can I speak to your manager?&lt;/P&gt;
&lt;P&gt;Leah and K and I silently&amp;nbsp;&lt;EM&gt;boggled&lt;/EM&gt; -- there is no other word for it -- at each other for a moment. Where on earth did she imagine that&amp;nbsp;a&amp;nbsp;&lt;EM&gt;manager&lt;/EM&gt; was going to emerge from? There was a counter, behind that, a trailer with a wok in it, behind that, &lt;EM&gt;jungle&lt;/EM&gt;, and behind that, &lt;EM&gt;huge jagged lava rocks&lt;/EM&gt; followed immediately by &lt;EM&gt;the Pacific Ocean&lt;/EM&gt;. And what sort of &lt;EM&gt;management structure&lt;/EM&gt; does she&amp;nbsp;think one really needs to manage&amp;nbsp;a single guy selling pineapple fried rice at the side of a highway? My conclusion: &lt;EM&gt;people have strange beliefs. &lt;/EM&gt;Sometimes their beliefs cause them to leave in a huff with neither fish nor chips, even &lt;EM&gt;when fish and chips are both plentiful and reasonably priced&lt;/EM&gt;. Hopefully she had better luck in Hana.&lt;/P&gt;
&lt;P&gt;Anyway, enough travelogue. Regarding the puzzle from last time: the code is correct, and compiles without issue. I was quite surprised when I first learned that; it certainly looks like&amp;nbsp;it violates our rule about not using the same simple name to mean&amp;nbsp;two different things in&amp;nbsp;one block.&lt;/P&gt;
&lt;P&gt;The key is to understanding why this is legal is&amp;nbsp;that the query comprehensions and foreach loops are specified as &lt;EM&gt;syntactic sugars&lt;/EM&gt; for another program, and it is &lt;EM&gt;that&lt;/EM&gt; program which is actually analyzed for correctness. Our original program:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static void Main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int[] data = { 1, 2, 3, 1, 2, 1 };&lt;BR&gt;&amp;nbsp; foreach (var m in from m in data orderby m select m)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.Write(m);&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;is transformed into&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static void Main()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int[] data = { 1, 2, 3, 1, 2, 1 };&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;int&amp;gt; e = ((IEnumerable&amp;lt;int&amp;gt;)(data.OrderBy(m=&amp;gt;m)).GetEnumerator();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int m;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while(e.MoveNext())&lt;BR&gt;&amp;nbsp;&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; m = (int)(int)e.Current;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.Write(m);&lt;BR&gt;&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; finally&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (e != null) ((IDisposable)e).Dispose();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&lt;/SPAN&gt;There are five usages of m in this transformed program; it is:&lt;/P&gt;
&lt;P&gt;1) declared as the formal parameter of a lambda.&lt;BR&gt;2) used in the body of the lambda; here it refers to the formal parameter.&lt;BR&gt;3) declared as a local variable&lt;BR&gt;4) written to in the loop; here it refers to the local variable&lt;BR&gt;5) read from in the loop; here it refers to the local variable&lt;/P&gt;
&lt;P&gt;Is there any usage of a local variable before its declaration? No. &lt;/P&gt;
&lt;P&gt;Are there any two declarations that have the same name in the same declaration space? It would appear so. The body of Main defines a local variable declaration space, and clearly the body of Main contains, indirectly, two declarations for m, one as a formal lambda parameter and one as a local. But I said last time that local variable declaration spaces have special rules for determining overlaps. It is illegal for a local variable declaration space to directly contain a declaration such that another nested local variable declaration space contains a declaration of the same name. But an outer declaration space which indirectly contains two such declarations is not&amp;nbsp; an error. So in this case, no, there are no local variable declarations spaces which directly contain a declaration for m, such that a nested local variable declaration space also directly contains a declaration for m. Our two local variable declarations spaces which directly contain a declaration for m do not overlap anywhere.&lt;/P&gt;
&lt;P&gt;Is there any declaration space which contains two inconsistent usages of the simple name m? Yes, again, the outer block of Main contains two inconsistent usages of m. But again, this is not relevant. The question is whether any declaration space directly containing m has an inconsistent usage. Again, we have two declaration spaces but they do not overlap each other, so there's no problem here either.&lt;/P&gt;
&lt;P&gt;The thing which makes this legal, interestingly enough, is the generation of the loop variable declaration logically within the try block. Were it to be generated outside the try block then this would be a violation of the rule about inconsistent usage of a simple name throughout a declaration space.&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909324" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Puzzles" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx" /><category term="Dialogue" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx" /><category term="declaration spaces" scheme="http://blogs.msdn.com/ericlippert/archive/tags/declaration+spaces/default.aspx" /><category term="scope" scheme="http://blogs.msdn.com/ericlippert/archive/tags/scope/default.aspx" /><category term="customer service" scheme="http://blogs.msdn.com/ericlippert/archive/tags/customer+service/default.aspx" /><category term="Simple Names" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Simple+Names/default.aspx" /><category term="maui" scheme="http://blogs.msdn.com/ericlippert/archive/tags/maui/default.aspx" /></entry><entry><title>Simple names are not so simple</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx</id><published>2009-11-02T14:23:00Z</published><updated>2009-11-02T14:23:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;C# has many rules that are designed to prevent some common sources of bugs and encourage good programming practices. So many, in fact, that it is often quite confusing to sort out exactly which rule has been violated. I thought I might spend some time talking about what the different rules are. We'll finish up with a puzzle.&lt;/P&gt;
&lt;P&gt;To begin with, it will be vital to understand &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/08/03/what-s-the-difference-part-two-scope-vs-declaration-space-vs-lifetime.aspx"&gt;the difference between &lt;EM&gt;scope&lt;/EM&gt; and &lt;EM&gt;declaration space&lt;/EM&gt;&lt;/A&gt;. To refresh your memory of my earlier article: the &lt;EM&gt;scope&lt;/EM&gt; of an entity is &lt;EM&gt;the region of text in which that entity may be referred to by its unqualified name&lt;/EM&gt;. A &lt;EM&gt;declaration space&lt;/EM&gt; is a region of text in which &lt;EM&gt;no two things may have the same name &lt;/EM&gt;(with an exception for methods which differ by signature.) A "local variable declaration space" is a particular kind of declaration space used for declaring local variables; local variable declaration spaces have special rules for determining when they overlap.&lt;/P&gt;
&lt;P&gt;The next thing that you have to understand to make any sense o this is what a "simple name" is. A &lt;EM&gt;simple name&lt;/EM&gt; is always either just a plain identifier, like "x", or, in some cases, a plain identifier followed by a type argument list, like "Frob&amp;lt;int, string&amp;gt;". &lt;/P&gt;
&lt;P&gt;Lots of things are treated as "simple names" by the compiler: local variable declarations, lambda parameters, and so on, always have the first form of simple name in their declarations. When you say "Console.WriteLine(x);" the "Console" and "x" are simple names but the "WriteLine" is not. Confusingly, there are some textual entities which have the form of simple names, but are not treated as simple names by the compiler. We might talk about some of those situations in later fabulous adventures.&lt;/P&gt;
&lt;P&gt;So, without further ado, here are some relevant rules which are frequently confused. It's rules 3 and 4 that people find particularly confusing.&lt;/P&gt;
&lt;P&gt;1) It is illegal to refer to a local variable before its declaration. (This seems reasonable I hope.)&lt;BR&gt;2) It is illegal to have two local variables of the same name in the same local variable declaration space or nested local variable declaration spaces.&lt;BR&gt;3) Local variables are in scope throughout the entire block in which the declaration occurs. This is in contrast with C++, in which local variables are in scope in their block only at points after the declaration.&lt;BR&gt;4) For every occurrence of a simple name, whether in a declaration or as part of an expression, all uses of that simple name within the immediately enclosing local variable declaration space must refer to the same entity.&lt;/P&gt;
&lt;P&gt;The purpose of all of these rules is to prevent the class of bugs in which the reader/maintainer of the code is tricked into believing they are referring to one entity with a simple name, but are in fact accidentally referring to another entity entirely. These rules are in particular designed to prevent nasty surprises when performing what ought to be safe refactorings. &lt;/P&gt;
&lt;P&gt;Consider a world in which we did not have rules 3 and 4. In that world, this code would be legal:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is hard on the person reading the code, who has a reasonable expectation that the two "Console.WriteLine(x)" lines do in fact both print out the contents of the same variable. But it is particularly nasty for the maintenance programmer who wishes to impose a reasonable coding standard upon this body of code. "Local variables are declared at the top of the block where they're used" is a reasonable coding standard in a lot of shops. But changing the code to:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // no longer means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // no longer means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;} &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;changes the meaning of the code! We wish to discourage authoring of multi-hundred-line methods, but making it harder and more error-prone to refactor them into something cleaner is not a good way to achieve that goal.&lt;/P&gt;
&lt;P&gt;Notice that the original version of this program, rule 3 means that the program violates rule 1 -- the first usage of "x" is treated as a reference to the local before it is declared. The fact that it violates rule 1 because of rule 3 is precisely what prevents it from being a violation of rule 4! The meaning of "x" is consistent throughout the block; it always means the local, and therefore is sometimes used before it is declared. If we scrapped rule 3 then this would be a violation of rule 4, because we would then have two inconsistent meanings for the simple name "x" within one block.&lt;/P&gt;
&lt;P&gt;Now, these rules do not mean that you can refactor willy-nilly. We can still construct situations in which similar refactorings fail. For example:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;class C&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; int x;&lt;BR&gt;&amp;nbsp; void M()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; x = 20; // means "this.x";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "this.x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 100 lines of code&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 10;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x); // means "local x"&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This is perfectly legal. We have the same simple name being used two different ways in two different blocks, but the immediately enclosing block of each usage does not overlap that of any other usage. The local variable is in scope throughout its immediately enclosing block, but that block does not overlap the block above. In this case, it is safe to refactor the declaration of the local to the top of its block, but not safe to refactor the declaration to the top of the outermost block; that would change the meaning of "x" in the first block. Moving a declaration up is almost always a safe thing to do; moving it out is not necessarily safe. &lt;/P&gt;
&lt;P&gt;Now that you know all that, here's a puzzle for you, a puzzle that I got completely wrong the first time I saw it:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;using System.Linq;&lt;BR&gt;class Program&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; static void Main()&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int[] data = { 1, 2, 3, 1, 2, 1 };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var m in from m in data orderby m select m)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.Console.Write(m);&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;It certainly looks like name "m" is being used multiple times to mean different things. Is this program legal? If yes, why do the rules for not re-using simple names&amp;nbsp;not apply? If no, precisely what rule has been violated?&amp;nbsp; &lt;/P&gt;
&lt;P&gt;[Eric is on vacation; this posting was pre-recorded.]&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909292" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Puzzles" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Puzzles/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="declaration spaces" scheme="http://blogs.msdn.com/ericlippert/archive/tags/declaration+spaces/default.aspx" /><category term="scope" scheme="http://blogs.msdn.com/ericlippert/archive/tags/scope/default.aspx" /><category term="Simple Names" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Simple+Names/default.aspx" /><category term="local variables" scheme="http://blogs.msdn.com/ericlippert/archive/tags/local+variables/default.aspx" /><category term="refactoring" scheme="http://blogs.msdn.com/ericlippert/archive/tags/refactoring/default.aspx" /></entry><entry><title>I have a Fit, but a lack of Focus.</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/29/i-have-a-fit-but-a-lack-of-focus.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/29/i-have-a-fit-but-a-lack-of-focus.aspx</id><published>2009-10-29T13:54:00Z</published><updated>2009-10-29T13:54:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Here's a statement I read the other day about making comparisons between objects of reference type in C#:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Object.ReferenceEquals(x,y) returns true if and only if x and y refer to the same object.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;True or false?&lt;/P&gt;
&lt;P&gt;My wife Leah recently acquired a Honda Fit, thanks to the imminant failure of the automatic transmission solenoids in her aged Honda Civic. The back seats in the Fit fold down flat. You can fit a llama or a whole pile of hula hoops or whatever into that thing. It's quite handy. Not what I would call a powerful engine by any means, but for quick trips around town, it certainly gets the job done.&lt;/P&gt;
&lt;P&gt;Since we were married when she bought the car, and we continue to be married, what's mine is hers and what's hers is mine. So if x = Eric's Honda Fit, and y = Leah's Honda Fit, then x and y are "reference equals". Those two things refer to the same object, viz, the shiny black object full of llamas and hula hoops in my driveway.&lt;/P&gt;
&lt;P&gt;Now, we could have bought a different car. Say, a Ford Focus. But we did not. We own a total of zero Ford Foci. Suppose I said that x = Eric's Ford Focus, and y = Leah's Ford Focus. What's the sensible way to characterize the nature of x and y? Do we say that x and y refer to the same Ford Focus, namely that they refer to the Ford Focus&amp;nbsp;that does not exist? The mind boggles at the repugnant and paradoxical implication that there exists a Ford Focus that is the Ford Focus&amp;nbsp;that does not exist! (*) Rather, the right way to characterize this is to say that neither x nor y refer to any object. They're "null references" -- references that do not have any referent, but rather, capture the notion of "a lack of referent".&lt;/P&gt;
&lt;P&gt;And that's why it's incorrect to say that Object.ReferenceEquals(x,y) returns true&amp;nbsp;&lt;STRONG&gt;if and only if&lt;/STRONG&gt;&amp;nbsp;x and y refer to the &lt;STRONG&gt;same object&lt;/STRONG&gt;.If x and y both do not refer to any object, then clearly they do not&lt;EM&gt; refer to&lt;/EM&gt; &lt;EM&gt;the same object&lt;/EM&gt;, because&amp;nbsp;&lt;EM&gt;neither refers to an object in the first place&lt;/EM&gt;. The correct way to characterize the behaviour of reference equality is&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Object.ReferenceEquals(x,y) returns true&amp;nbsp;if and only if&amp;nbsp;either x and y refer to the same object, &lt;EM&gt;or x and y are both null references.&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;***********&lt;/P&gt;
&lt;P&gt;(*) And yet I am a fan of the "null object pattern". Life is just full of these little contradictions.&lt;/P&gt;
&lt;P mce_keep="true"&gt;[Eric is on vacation this week; this posting is pre-recorded.]&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9908258" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="myths" scheme="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx" /><category term="reference equality" scheme="http://blogs.msdn.com/ericlippert/archive/tags/reference+equality/default.aspx" /><category term="Honda fit" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Honda+fit/default.aspx" /><category term="Ford Focus" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Ford+Focus/default.aspx" /></entry><entry><title>Some new videos</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/26/some-new-videos.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/26/some-new-videos.aspx</id><published>2009-10-26T13:17:00Z</published><updated>2009-10-26T13:17:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Somehow it has happened again; people just keep on recording videos of me and putting them on the internet. &lt;/P&gt;
&lt;P&gt;In these videos you find out what I look like when lit from above and behind. Kinda spooky. We should have made the room entirely dark and held a flashlight underneath my face. That would be, like, &lt;A class="" href="http://xenon.xe.net/inthumor/ih_026.htm" mce_href="http://xenon.xe.net/inthumor/ih_026.htm"&gt;ten times scarier&lt;/A&gt;. Anyway, if you're interested in me blathering on about my favourite feature in C# 4, covariance and contravariance of interface and delegate types, here are two little demo videos: &lt;A class="" href="http://msdn.microsoft.com/en-us/vcsharp/ee672314.aspx" mce_href="http://msdn.microsoft.com/en-us/vcsharp/ee672314.aspx"&gt;Part One&lt;/A&gt;, &lt;A class="" href="http://msdn.microsoft.com/en-us/vcsharp/ee672319.aspx" mce_href="http://msdn.microsoft.com/en-us/vcsharp/ee672319.aspx"&gt;Part Two&lt;/A&gt;. (There seems to be some minor sound sync issues here and there, but it's not really a problem; most of the&amp;nbsp;audio is voice-over.)&lt;/P&gt;
&lt;P&gt;Charlie has been crazy busy getting these little videos together; here are some more of his recent efforts, including some good ones from my colleagues Chris and Sam talking about all the other far more awesome features of C# 4.0: dynamic interop, improved interop with Office, named and optional parameters, and so on. Links to all of our recent videos are here: &lt;A href="http://blogs.msdn.com/charlie/archive/2009/10/19/community-convergence-lvi.aspx" mce_href="http://blogs.msdn.com/charlie/archive/2009/10/19/community-convergence-lvi.aspx"&gt;http://blogs.msdn.com/charlie/archive/2009/10/19/community-convergence-lvi.aspx&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Have an amusing and safe Hallowe'en -- I'll be going to Hallowe'en parties on a small island this year, just for a change of pace.&lt;/P&gt;
&lt;P mce_keep="true"&gt;[Eric is on vacation this week; this posting was pre-recorded]&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9911473" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Video" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Video/default.aspx" /><category term="Covariance and Contravariance" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx" /><category term="C# 4.0" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx" /></entry><entry><title>Begging the question</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/22/begging-the-question.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/22/begging-the-question.aspx</id><published>2009-10-22T13:23:00Z</published><updated>2009-10-22T13:23:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;In my last post I described the syllogism "&lt;EM&gt;Photogenic people look good in photograps; Michelle Pfeiffer is photogenic; therefore, Michelle Pfeiffer looks good in photographs&lt;/EM&gt;" as "begging the question". A few people commented on that, so I thought I'd address this point of English usage.&lt;/P&gt;
&lt;P&gt;In modern usage, "begging the question" has come to mean nothing more than "&lt;EM&gt;the situation suggests that an obvious question to raise at this time is blah blah blah&lt;/EM&gt;."&amp;nbsp;For example, "&lt;EM&gt;The global financial meltdown begs the question: was there insufficient federal oversight of the American mortgage industry?&lt;/EM&gt;"&amp;nbsp;Though this usage is certainly common in civic discourse and the media, it is&amp;nbsp;entirely a modern departure&amp;nbsp;from the historic usage of the phrase. I try to eschew this modern usage when I say "begs the question".&lt;/P&gt;
&lt;P&gt;"Begs the question" is also sometimes used to mean "this argument raises additional questions which require additional investigation before we can accept the argument". Though this is considerably &lt;EM&gt;closer&lt;/EM&gt; to the traditional definition of the phrase, this is also not exactly what I mean.&lt;/P&gt;
&lt;P&gt;When I say "begs the question",&amp;nbsp;I mean it in the traditional sense of "this argument is fallacious because it takes as a premise an assumption which is at least as strong as the thing being proven, and is therefore an unwarranted assumption."&lt;/P&gt;
&lt;P&gt;Let me give you another example of question begging, in the traditional sense, which might be more clear.&lt;/P&gt;
&lt;P&gt;Suppose I asked "why&amp;nbsp;are diamonds very hard but&amp;nbsp;butter is very soft?" and you answered "diamond and butter are both made out of atoms; the atoms of diamonds are hard and the atoms of butter are soft." You would have begged the question; your answer to my question "why are some things hard and some things soft" is "because some things are made out of stuff that is hard and some things are made out of stuff that is soft" -- that is, you've avoided answering the question&amp;nbsp;by providing&amp;nbsp;an "explanation" that itself cannot be understood without answering the original question -- namely, &lt;EM&gt;why&lt;/EM&gt; is some stuff hard and some stuff soft? This pseudo-explanation has no predictive power; it doesn't tell us anything new, it just circles back on itself. The explanatory assumption -- that some atoms are hard and some atoms are soft -- is &lt;EM&gt;stronger&lt;/EM&gt; than&amp;nbsp;the thing we are trying to investigate -- the hardness and softness of two substances.&lt;/P&gt;
&lt;P&gt;A non-question-begging answer would be "diamond and butter are both made of atoms; the atoms of a diamond are all identical and arranged in a stable, rigid lattice where every point in the lattice is reinforced by a strong bond to four other points. The atoms of butter are a disorganized collection of many different atoms grouped into different kinds of relatively complex molecules; though the molecules themselves are quite strong, each molecule of butter holds weakly to each other molecule. It takes only a small force to disrupt the loose arrangement of butter molecules but a very large force to disrupt the strong arrangement of diamond atoms. We perceive this difference in required force as 'hardness' on the human scale, but in fact it is a property that arises from the sub-microscopic-scale properties of each substance."&lt;/P&gt;
&lt;P&gt;Now, this explanation does *raise* more questions. It raises questions like "why are some lattices strong and some weak?" and "why are some objects composed of many different kinds of atoms organized into molecules, and some composed of just one atom?" Question-begging is not the act of raising more questions. &lt;EM&gt;Every&lt;/EM&gt; good explanation raises more questions. What makes this explanation a good one is that&amp;nbsp;it is &lt;EM&gt;testable&lt;/EM&gt; and has &lt;EM&gt;predictive power&lt;/EM&gt;; we can investigate the hardness or softness of other substances, and make predictions about what sorts of atomic structures they will have -- or, vice versa, we can look at an atomic structure and try to figure out from it how hard the substance will be. We can invent other techniques for determining atomic structure, like x-ray diffraction crystallography or spectroscopic analysis, and use those to cross-check our "atomic theory of hardness".&lt;/P&gt;
&lt;P&gt;But the "because she's photogenic" pseudo-explanation is clearly question-begging. Why does she look so good? Because she's photogenic. Why is she photogenic? Because she looks so good. We have learned nothing about photogenicity (or the lovely Ms. Pfeiffer). &lt;/P&gt;
&lt;P&gt;Similarly, if you ask "why is this code thread-safe?" and the answer is "because it can be correctly called on multiple threads", we've begged the question. Why is it thread-safe? Because it's correct. Why is it correct? Because it's thread-safe. Again, we have learned nothing about the nature of thread safety. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9909508" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="English Usage" scheme="http://blogs.msdn.com/ericlippert/archive/tags/English+Usage/default.aspx" /><category term="Michelle Pfeiffer" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Michelle+Pfeiffer/default.aspx" /><category term="Begging the question" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Begging+the+question/default.aspx" /></entry><entry><title>What is this thing you call "thread safe"?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call-thread-safe.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call-thread-safe.aspx</id><published>2009-10-19T13:50:00Z</published><updated>2009-10-19T13:50:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;&lt;STRONG&gt;Caveat: I am not an expert on multi-threading programming.&lt;/STRONG&gt; In fact, I wouldn't even say that I am &lt;EM&gt;competent&lt;/EM&gt; at it. My whole career, I've needed to write code to spin up a secondary worker thread probably less than half a dozen times. So take everything I say on the subject with some skepticism.&lt;/P&gt;
&lt;P&gt;A question I'm frequently asked: "&lt;EM&gt;is this code &lt;STRONG&gt;thread safe&lt;/STRONG&gt;?&lt;/EM&gt;" To answer the question, clearly we need to know what "thread safe" means.&lt;/P&gt;
&lt;P&gt;But before we get into that, there's something I want to clear up first. A question I am less frequently asked is "&lt;EM&gt;Eric, why does Michelle Pfeiffer always look so good in photographs?&lt;/EM&gt;"&amp;nbsp;To help answer this pressing question, I&amp;nbsp;consulted &lt;A class="" href="http://en.wikipedia.org/wiki/Photogenic" mce_href="http://en.wikipedia.org/wiki/Photogenic"&gt;Wikipedia&lt;/A&gt;:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;"A&amp;nbsp;&lt;B&gt;photogenic&lt;/B&gt; subject&amp;nbsp;is a subject that usually appears physically attractive or striking in photographs."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Why&amp;nbsp;does Michelle Pfeiffer always look so good in photographs? &lt;STRONG&gt;&lt;EM&gt;Because she's photogenic&lt;/EM&gt;.&lt;/STRONG&gt; Obviously.&lt;/P&gt;
&lt;P&gt;Well, I'm glad we've cleared up that mystery, but I seem to have wandered somehwat from the subject at hand. Wikipedia is &lt;A class="" href="http://en.wikipedia.org/wiki/Thread_safety" mce_href="http://en.wikipedia.org/wiki/Thread_safety"&gt;just as helpful in defining thread safety&lt;/A&gt;:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp;"A piece of code is &lt;B&gt;thread-safe&lt;/B&gt; if it functions correctly during simultaneous execution by multiple threads."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As with photogenicity, this&amp;nbsp;is obvious question-begging. When we ask "is this code &lt;EM&gt;thread safe&lt;/EM&gt;?" all we are really asking is "is this code &lt;EM&gt;correct&lt;/EM&gt; &lt;EM&gt;when called in a particular manner&lt;/EM&gt;?"&amp;nbsp;So how do we determine if the code is correct? &lt;STRONG&gt;We haven't actually explained anything here.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Wikipedia goes on:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&lt;EM&gt;"In particular, it must satisfy the need for multiple threads to access the same shared data, ..."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;This seems fair; this scenario is almost always what people mean when they talk about thread safety. But then:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&lt;EM&gt;"...and the need for a shared piece of data to be accessed by only one thread at any given time."&lt;/EM&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;Now we're talking about techniques for &lt;EM&gt;creating&lt;/EM&gt; thread safety, not &lt;EM&gt;defining&lt;/EM&gt; what thread safety means. Locking data so that it can only be accessed by one thread at a time is just one possible&amp;nbsp;technique for creating thread safety; it is not itself the definition of thread safety.&lt;/P&gt;
&lt;P mce_keep="true"&gt;My point is not that the definition is &lt;EM&gt;wrong&lt;/EM&gt;; as informal definitions of thread safety&amp;nbsp;go, this one is not terrible.&amp;nbsp;Rather, my point is&amp;nbsp;that the&amp;nbsp;definition indicates that the concept itself is &lt;EM&gt;completely vague&lt;/EM&gt; and essentially means nothing more than "behaves correctly in some situations". Therefore, when I'm asked "is this code thread safe?" I always have to push back and ask "what are the &lt;EM&gt;exact&lt;/EM&gt; &lt;EM&gt;threading scenarios&lt;/EM&gt; you are concerned about?" and "exactly what is &lt;EM&gt;correct behaviour&lt;/EM&gt; of the object in every one of those scenarios?"&lt;/P&gt;
&lt;P mce_keep="true"&gt;Communication problems arise when&amp;nbsp;people with different answers to those questions try to communicate about thread safety. For example, suppose I told you that I have a "threadsafe mutable queue" that you can use in your program.&amp;nbsp;You then cheerfully write the following code that runs on one thread while another thread is busy adding and removing items from the mutable queue:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;if (!queue.IsEmpty) Console.WriteLine(queue.Peek());&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Your code then crashes when the Peek throws a QueueEmptyException. What is going on here? I&amp;nbsp;said this&amp;nbsp;thing was thread safe, and yet your code is crashing in a multi-threaded scenario.&lt;/P&gt;
&lt;P mce_keep="true"&gt;When I said "the queue is threadsafe" I meant that the queue maintains its internal state consistently no matter what sequence of &lt;EM&gt;individual&lt;/EM&gt; operations are happening on other threads. But I did not mean that you can use my queue in any scenario that requires &lt;EM&gt;logical consistency maintained across multiple operations in a sequence&lt;/EM&gt;. In short, my opinion of "correct behaviour" and your opinion of the same differed because what we thought of as the relevant scenario was completely different. I care only about not crashing, but you care about being able to reason logically about the information returned from each method call.&lt;/P&gt;
&lt;P mce_keep="true"&gt;In this example, you and I are probably&amp;nbsp;talking about different kinds of thread safety. Thread safety of mutable data structures is usually all about ensuring that the operations on the shared data always operate on the &lt;STRONG&gt;most up-to-date&lt;/STRONG&gt; state of the shared data as it mutates, even if that means that a particular combination of operations appears to be &lt;STRONG&gt;logically inconsistent&lt;/STRONG&gt;, as in our example above. Thread safety of immutable data structures is all about ensuring that use of&amp;nbsp;the data across all operations is &lt;STRONG&gt;logically consistent&lt;/STRONG&gt;, at the expense of the fact that you're looking at an&amp;nbsp;immutable&amp;nbsp;snapshot that might be &lt;STRONG&gt;out-of-date&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The problem here is that the choice about whether to access the first element or not is based on "stale" data. Designing a truly thread-safe mutable data structure in a world where &lt;EM&gt;nothing is allowed to be stale&lt;/EM&gt; can be&amp;nbsp;very difficult. Consider what you'd have to do in order to make the "Peek" operation above actually threadsafe. You'd need a new method:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;if (!queue.Peek(out first)) Console.WriteLine(first);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Is this "thread safe"? It certainly seems better.&amp;nbsp;But what if after the Peek, a different thread dequeues the queue? Now you're not crashing, but you've changed the behaviour of the previous program considerably. In the previous program, if, after the test there was a dequeue on another thread that changed what the first element was, then you'd either crash or&amp;nbsp;print out the up-to-date first element in the queue. Now you're printing out a &lt;EM&gt;stale&lt;/EM&gt; first element. Is that &lt;EM&gt;correct&lt;/EM&gt;? Not if we &lt;EM&gt;always&lt;/EM&gt; want to operate on up-to-date data!&lt;/P&gt;
&lt;P mce_keep="true"&gt;But wait a moment -- actually, the &lt;EM&gt;previous&lt;/EM&gt; version of the code had this problem as well. What if the dequeue on the other thread happened &lt;EM&gt;after&lt;/EM&gt; the call to Peek succeeded but &lt;EM&gt;before&lt;/EM&gt; the Console.WriteLine call executed? Again, you could be printing out stale data.&lt;/P&gt;
&lt;P mce_keep="true"&gt;What if you want to ensure that you are always printing out up-to-date data? What you really need to make this threadsafe is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P mce_keep="true"&gt;queue.DoSomethingToHead(first=&amp;gt;{Console.WriteLine(first);});&lt;/P&gt;&lt;/SPAN&gt;
&lt;P mce_keep="true"&gt;Now the queue&amp;nbsp;author and the queue user agree on what the relevant scenarios are, so this is truly threadsafe. Right?&lt;/P&gt;
&lt;P mce_keep="true"&gt;Except... there could be something super-complicated in that delegate. What if whatever is in the delegate happens to cause an event that triggers code to run on another thread, which in turn causes some queue operation to run, which in turn blocks in such a manner that we've produced a deadlock? Is a deadlock "correct behaviour"? And if not, is&amp;nbsp;this method truly "safe"?&lt;/P&gt;
&lt;P mce_keep="true"&gt;Yuck.&lt;/P&gt;
&lt;P mce_keep="true"&gt;By now you take my point I'm sure.&amp;nbsp;As I pointed out earlier, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2008/08/19/tasty-beverages.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2008/08/19/tasty-beverages.aspx"&gt;it is unhelpful to say that a building or a hunk of code is "secure" without somehow communicating &lt;STRONG&gt;which&amp;nbsp;threats&lt;/STRONG&gt;&amp;nbsp;the utilized security mechanism are and are not&amp;nbsp;proof against.&lt;/A&gt; Similarly,&amp;nbsp;&lt;STRONG&gt;it is unhelpful to say that code is "thread safe" without somehow communicating what undesirable&amp;nbsp;behaviors the utilized thread safety mechanisms do and do not prevent.&lt;/STRONG&gt; "Thread safety" is nothing more nor less than a code contract, like any other code contract. You agree to talk to an object in a particular manner, and it agrees to give you correct results if you do so; working out exactly what that manner is, and what the correct responses are, is a potentially tough problem.&lt;/P&gt;
&lt;P mce_keep="true"&gt;************&lt;/P&gt;
&lt;P&gt;(*) Yes, I'm aware that if I think something on Wikipedia is wrong, I can change it. There are two reasons why I should not do so.&amp;nbsp;First, as&amp;nbsp;I've already stated I'm not an expert in this area; I leave it to the experts to sort out amongst themselves what the right thing to say here is. And second, my point is not that the Wikipedia page is wrong, but rather that it illustrates that the term itself is&amp;nbsp;vague by nature.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9906219" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Threading" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx" /><category term="Immutability" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Immutability/default.aspx" /><category term="Wikipedia" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Wikipedia/default.aspx" /><category term="Michelle Pfeiffer" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Michelle+Pfeiffer/default.aspx" /><category term="Begging the question" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Begging+the+question/default.aspx" /></entry><entry><title>As Timeless As Infinity</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/15/as-timeless-as-infinity.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/15/as-timeless-as-infinity.aspx</id><published>2009-10-15T13:25:00Z</published><updated>2009-10-15T13:25:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt; Recently I found out about a peculiar behaviour concerning division by zero in floating point numbers in C#. It does not throw an exception, as with integer division,&amp;nbsp;but rather returns an "infinity". Why is that?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; As I've often said, "why" questions are difficult for me&amp;nbsp;to answer. My first attempt at an answer to a "why" question is usually "because that's what the specification says to do"; this time is no different. The C# specification says to do that in section 4.1.6. But we're only doing that because that's what&amp;nbsp;the IEEE standard for floating point arithmetic says to do. We wish to be compliant with the established industry standard. See &lt;A href="http://en.wikipedia.org/wiki/IEEE_754-1985" mce_href="http://en.wikipedia.org/wiki/IEEE_754-1985"&gt;IEEE standard 754-1985&lt;/A&gt; for details. Most floating point&amp;nbsp;arithmetic&amp;nbsp;is done in hardware these days, and most hardware is compliant with this specification.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;It seems to me that division by zero is a bug no matter how you look at it!&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; Well, since clearly that is not how the members of the IEEE standardization committee looked at it in 1985, your statement that it must be a bug "no matter how you look at it" must be incorrect. Some industry experts do not look at it that way.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Good point. What motivated this design decision?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; I wasn't there; I was busy playing&amp;nbsp;Jumpman on my Commodore 64 at the time. But my educated guess is that &lt;STRONG&gt;it is desirable for all possible operations on all floats to produce a well-defined float result&lt;/STRONG&gt;. Mathematicians would call this a "closure" property; that is, the set of floating point numbers is "closed" over all operations.&lt;/P&gt;
&lt;P&gt;Positive infinity seems like a reasonable choice for dividing a positive number by zero. It seems plausible because of course the limit of 1 / x as x goes to zero (from above)&amp;nbsp;is "positive infinity", so why shouldn't 1/0 be the number "positive infinity"?&lt;/P&gt;
&lt;P&gt;Now, speaking &lt;EM&gt;as a mathematician&lt;/EM&gt;, I find that argument specious. A thing&amp;nbsp;and its limit need not have any particular property in common; it is fallacious to reason that just because, say, a sequence has a particular limit that a fact about the limit is also a fact about the sequence. Mathematically, "positive infinity" (in the sense of a limit of a real-valued function; let's leave transfinite ordinals, hyperbolic geometry, and all of that&amp;nbsp;other stuff out of this discussion)&amp;nbsp;is not a number at all and should not be treated as one; rather, it's a terse way of saying "the limit does not exist because the sequence diverges upwards". &lt;/P&gt;
&lt;P&gt;When we divide by zero, essentially what we are saying is "solve the equation x * 0 = 1"; the solution to that equation is not "positive infinity", it is "I cannot because there is no solution to that equation". It's just the same as asking to solve the equation "x + 1 = x" -- saying "x is positive infinity" is not a solution; there is no solution.&lt;/P&gt;
&lt;P&gt;But speaking &lt;EM&gt;as a practical engineer&lt;/EM&gt; who uses floating point numbers to do an imprecise approximation of ideal arithmetic, this seems like a perfectly reasonable choice. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;But surely it is impossible for the hardware to represent "infinity".&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric:&lt;/STRONG&gt; It certainly is possible. You've got 32 bits in a single-precision float; that's over four billion possible floats. All bit patterns of the form &lt;/P&gt;
&lt;P&gt;?11111111??????????????????????? &lt;/P&gt;
&lt;P&gt;are reserved for "not-a-number" values. That's over sixteen million possible NaN combinations. Two of those sixteen million NaN bit patterns are reserved to mean positive and negative infinity. Positive infinity is the bit pattern 01111111100000000000000000000000 and negative infinity is 11111111100000000000000000000000. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Do all languages and applications use this convention of division-by-zero-becomes-infinity?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;No.&amp;nbsp;For example, C#&amp;nbsp;and JScript do but&amp;nbsp;VBScript does not. VBScript gives an error if you do that.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Then how do language implementors get the desired behaviour for each language if these semantics are implemented by the hardware?&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;There are two basic techniques. First, many chips which implement this standard allow&amp;nbsp;the programmer&amp;nbsp;to make float division by zero an exception rather than an infinity. On the 80x87 chip, for example, you can use bit two of the precision control register to determine whether division by zero returns an infinity or&amp;nbsp;throws a hardware exception. &lt;/P&gt;
&lt;P&gt;Second, if you don't want it to be a hardware exception but do want it to be a software exception, then you can check bit two of the status register after each division;&amp;nbsp;it records whether there was&amp;nbsp;a recent divide-by-zero event. &lt;/P&gt;
&lt;P&gt;The latter strategy is used by VBScript; after we perform a division operation we check to see whether the status register recorded a divide-by-zero operation; if it did, then the VBScript runtime creates a divide-by-zero error and the usual VBScript error management&amp;nbsp;process takes over, same as any other error.&lt;/P&gt;
&lt;P&gt;Similar bits exist for other operations that seem like they might be better treated as exceptions, like numeric overflow.&lt;/P&gt;
&lt;P&gt;The existence of the "hardware exception" bits creates problems for the modern&amp;nbsp;language implementor, because we are now often in a world where code written in multiple languages from multiple vendors is running in the same process. Control bits on hardware are the ultimate "global state", and we all know how irksome it is to have global, public state that random code can stomp on. &lt;/P&gt;
&lt;P&gt;For example: I might be misremembering some details, but I seem to recall that Delphi-authored controls set the "overflows cause exceptions" bit. That is, the Delphi implementors did not use the VBScript strategy of "try it, allow it to succeed, and check to see whether the&amp;nbsp;overflow bit was set in the status register". Rather, they used the "make the hardware throw an exception and then catch the exception" strategy. This is deeply unfortunate.&amp;nbsp;When a VBScript script&amp;nbsp;calls a Delphi-authored control, the control flips the bit to force exceptions but it never "unflips" it. If, later on in the script, the VBScript program does an overflow, then we get an unhandled hardware exception because the bit is still set, even though the Delphi control might be long gone! I fixed that by saving away the state of the control register before calling into a component and restoring it when control returns. That's not ideal, but there's not much else we can do.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;User:&lt;/STRONG&gt;&amp;nbsp;Very enlightening! I will be sure to pass this information along to my coworkers. I would be delighted to see a blog post on this.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eric: &lt;/STRONG&gt;And here you go!&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9904452" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="VBScript" scheme="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx" /><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Floating Point Arithmetic" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Floating+Point+Arithmetic/default.aspx" /><category term="Dialogue" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx" /><category term="Language Design" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx" /><category term="exception handling" scheme="http://blogs.msdn.com/ericlippert/archive/tags/exception+handling/default.aspx" /><category term="Delphi" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Delphi/default.aspx" /></entry><entry><title>Absence of evidence is not evidence of absence</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/ericlippert/archive/2009/10/12/absence-of-evidence-is-not-evidence-of-absence.aspx" /><id>http://blogs.msdn.com/ericlippert/archive/2009/10/12/absence-of-evidence-is-not-evidence-of-absence.aspx</id><published>2009-10-12T13:51:00Z</published><updated>2009-10-12T13:51:00Z</updated><content type="html">&lt;DIV class=mine&gt;
&lt;P&gt;Today, two more subtly incorrect myths about C#.&lt;/P&gt;
&lt;P&gt;As you probably know, C# requires all local variables to be explicitly assigned before they are read, but assumes that all class instance field variables are initially assigned to default values. An explanation of why that is that I sometimes hear is "&lt;EM&gt;the compiler can easily prove that a local variable is not assigned, but it is much harder to prove that an instance&amp;nbsp;field is not assigned. And since the class's default constructor automatically assigns all instance fields to default values, you don't need to do the analysis for fields."&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Both statements are subtly incorrect.&lt;/P&gt;
&lt;P&gt;The first statement is incorrect because the compiler in fact cannot and does not prove that a local variable is not assigned. Proving that is (1) impossible, and (2) does not give us any useful information we can act upon. It's impossible because proving that a given variable is assigned a value is equivalent to solving the Halting Problem:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int x;&lt;BR&gt;if (/*condition requiring solution of the halting problem here*/) x = 10;&lt;BR&gt;print(x);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If what we wanted to do was prove that x was &lt;EM&gt;unassigned&lt;/EM&gt; then we would have to &lt;EM&gt;at compile time&lt;/EM&gt; prove that the condition was false.&amp;nbsp;Our compiler is not that sophisticated! &lt;/P&gt;
&lt;P&gt;But the deeper point here is that we're not interested in proving for certain that x is &lt;EM&gt;unassigned&lt;/EM&gt;. We're interested in proving for certain that x is &lt;EM&gt;assigned&lt;/EM&gt;! If we can prove that for certain, then x is "definitely assigned". If we cannot prove that for certain then x is "not definitely assigned". We're only interested in "definitely unassigned" insofar as "definitely unassigned" is a stronger version of "not definitely assigned". If x is read from when it is "not definitely assigned", that's a bug. &lt;/P&gt;
&lt;P&gt;That is, we're attempting to prove that x is assigned, and our failure to prove that at every point where it is read is what motivates the error. That failure could be because of a bona fide bug in your program, or it could be because our flow analyzer is extremely conservative. For example:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int x, y = 0;&lt;BR&gt;if (0 * y == 0) x = 10;&lt;BR&gt;print(x);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;You and I know that x is definitely assigned, but in C# 3 the compiler is &lt;EM&gt;deliberately&lt;/EM&gt; not smart enough to prove that. (Interestingly enough, it &lt;EM&gt;was&lt;/EM&gt; smart&amp;nbsp;enough in C# 2. &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/03/29/the-root-of-all-evil-part-two.aspx"&gt;I broke that to bring the compiler into line with&amp;nbsp;the spec; being smarter but in violation of the spec is not necessarily a good thing&lt;/A&gt;.)&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This example again shows that we do not prove that x is unassigned; if we did prove that, then clearly our prover would contain an error, since you and I both know that x is definitely assigned. Rather, we fail to prove that x is assigned.&lt;/P&gt;
&lt;P&gt;This is an interesting twist on&amp;nbsp;the believers vs skeptics argument that goes like this: the skeptic says "there's no reliable evidence that bigfoot exists, therefore, bigfoot does not exist". The believer says&amp;nbsp;"absence of reliable evidence is not itself evidence of absence; and yes, bigfoot&amp;nbsp;does exist". In both cases, reasoning from a position of lacking reliable evidence is seldom good reasoning! But in our case, it is precisely &lt;EM&gt;because&lt;/EM&gt; we lack reliable evidence that we are coming to the conclusion that we do not know enough to allow you to read from x.&lt;/P&gt;
&lt;P&gt;(The relevant principle for tentatively concluding that bigfoot is mythical based on a lack of reliable evidence&amp;nbsp;is "extraordinary claims require extraordinary evidence". &lt;EM&gt;It&lt;/EM&gt; &lt;EM&gt;is reasonable to assume that&amp;nbsp;an extraordinary claim is false until reliable evidence is produced&lt;/EM&gt;.&amp;nbsp;When overwhelmingly reliable evidence is produced of an extraordinary claim -- say, the extraordinary claim that&amp;nbsp;time itself slows down when you move faster -- then it makes sense to believe the extraordinary claim. Overwhelming evidence has been provided for the theory of relativity, but not for the theory of bigfoot.)&lt;/P&gt;
&lt;P&gt;The second myth is that the default constructor of a class&amp;nbsp;initializes the fields to their default values. This can be shown to be false by several arguments. &lt;/P&gt;
&lt;P&gt;First, a class need not have a default constructor, and yet its fields are always observed to be initially assigned. If there is no default constructor, then something else must be initializing the fields. &lt;/P&gt;
&lt;P&gt;Second, even if a class does have a default constructor, there's no guarantee that it will be called. Some other constructor could be called.&lt;/P&gt;
&lt;P&gt;Third, the field initializers of a class run before any constructor body runs, therefore it cannot be the constructor body that does the initialization; that would be wiping out the results of the field initializers. &lt;/P&gt;
&lt;P&gt;Fourth, constructors can call other constructors; if each of those constructors was initializing the fields to zero, then that would be wasteful; we'd be unneccessarily re-initializing already-wiped-out fields. &lt;/P&gt;
&lt;P&gt;What actually happens is that the CLI memory allocator guarantees that the memory allocated for a given class instance will be initialized to all zeros before the constructor is called. By the time the constructors run the object is already freshly zeroed out&amp;nbsp;and ready to go.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9905526" width="1" height="1"&gt;</content><author><name>EricLippert</name><uri>http://blogs.msdn.com/members/EricLippert.aspx</uri></author><category term="C#" scheme="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx" /><category term="Science" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Science/default.aspx" /><category term="Memory Management" scheme="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx" /><category term="myths" scheme="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx" /><category term="relativity" scheme="http://blogs.msdn.com/ericlippert/archive/tags/relativity/default.aspx" /><category term="skepticism" scheme="http://blogs.msdn.com/ericlippert/archive/tags/skepticism/default.aspx" /><category term="definite assignment" scheme="http://blogs.msdn.com/ericlippert/archive/tags/definite+assignment/default.aspx" /><category term="constructors" scheme="http://blogs.msdn.com/ericlippert/archive/tags/constructors/default.aspx" /></entry></feed>