<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Fabulous Adventures In Coding : myths</title><link>http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx</link><description>Tags: myths</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>I have a Fit, but a lack of Focus.</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/29/i-have-a-fit-but-a-lack-of-focus.aspx</link><pubDate>Thu, 29 Oct 2009 13:54:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9908258</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9908258.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9908258</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/reference+equality/default.aspx">reference equality</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Honda+fit/default.aspx">Honda fit</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Ford+Focus/default.aspx">Ford Focus</category></item><item><title>Absence of evidence is not evidence of absence</title><link>http://blogs.msdn.com/ericlippert/archive/2009/10/12/absence-of-evidence-is-not-evidence-of-absence.aspx</link><pubDate>Mon, 12 Oct 2009 13:51:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9905526</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9905526.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9905526</wfw:commentRss><description>&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;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Science/default.aspx">Science</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/relativity/default.aspx">relativity</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/skepticism/default.aspx">skepticism</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/definite+assignment/default.aspx">definite assignment</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/constructors/default.aspx">constructors</category></item><item><title>Precedence vs order, redux</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/10/precedence-vs-order-redux.aspx</link><pubDate>Mon, 10 Aug 2009 17:06:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9823225</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9823225.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9823225</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Once more I'm revisting &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2008/05/23/precedence-vs-associativity-vs-order.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2008/05/23/precedence-vs-associativity-vs-order.aspx"&gt;the myth that order of&amp;nbsp;evaluation has any relationship to operator precedence in C#&lt;/A&gt;. Here's a version of this myth that I hear every now and then. Suppose you've got a field arr that is an array of ints, and some local variables index and value:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int index = 0;&lt;BR&gt;int value = this.arr[index++];&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;When all is said and done, value will contain the value that was in this.arr[0], and index will be 1, right? &lt;/P&gt;
&lt;P&gt;Right. Now, the myth. I often hear this explained as "because the ++ comes after the variable, the increment &lt;STRONG&gt;happens after&lt;/STRONG&gt; the array is dereferenced." &lt;/P&gt;
&lt;P&gt;Wrong! "After" implies &lt;STRONG&gt;a relationship based on a&amp;nbsp;sequence of events in time&lt;/STRONG&gt;, and the &lt;EM&gt;logical&lt;/EM&gt; sequence of events is extremely well-defined. The sequence of events for this program fragment is:&lt;/P&gt;
&lt;P&gt;1) store zero in "index"&lt;BR&gt;2) fetch a reference to this.arr and remember the result&lt;BR&gt;3) fetch the value in "index" and remember the result&lt;BR&gt;4) add one to the result of step 3 and remember the result&lt;BR&gt;5) store the result of step 4 in "index"&lt;BR&gt;6) look up the value in the reference from step 2 at the index from step 3 and remember the result&lt;BR&gt;7) store the result of step 6 in "value"&lt;/P&gt;
&lt;P&gt;I emphasize that the logical sequence is well-defined because the compiler, jitter and processor are all allowed to change the actual order of events for optimization purposes, subject to the restriction that the &lt;STRONG&gt;optimized&amp;nbsp;result must&amp;nbsp;be indistinguishable from the required result in single-threaded scenarios&lt;/STRONG&gt;. Reorderings &lt;EM&gt;are&lt;/EM&gt; sometimes observable in multithreaded scenarios. Analyzing the consequences of that fact&amp;nbsp;is&amp;nbsp;insanely complicated. I might blog about those issues&amp;nbsp;at some point if I feel brave. But for normal scenarios, you should assume that the ordering of events in time precisely follows the rules laid out in the specification.&lt;/P&gt;
&lt;P&gt;In fact, you can demonstrate that the increment happens before the indexing with this little self-referential gem:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int[] arr = {0};&lt;BR&gt;int value&amp;nbsp;= arr[arr[0]++];&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;What happens? First we fetch arr[0], which is 0, and remember that. Then we increment arr[0], so arr[0] becomes 1. Then we fetch the value of arr[0] because we remember the 0, and we get 1.&amp;nbsp; If we had done the increment &lt;EM&gt;after&lt;/EM&gt; the (outer) indexing then the result would be zero because the increment would not happen until after the value had been fetched.&lt;/P&gt;
&lt;P&gt;-- Eric is on vacation; this posting was prerecorded --&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9823225" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/precedence/default.aspx">precedence</category></item><item><title>Not everything derives from object</title><link>http://blogs.msdn.com/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx</link><pubDate>Thu, 06 Aug 2009 16:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9820268</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>43</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9820268.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9820268</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I hear a lot of myths about C#. Usually the myths have some germ of truth to them, like "&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx"&gt;value types are always allocated on the stack&lt;/A&gt;". If you replace "always" with "sometimes", then the incorrect mythical statement becomes correct.&lt;/P&gt;
&lt;P&gt;One I hear quite frequently is "in C# every type derives from object". Not true! &lt;/P&gt;
&lt;P&gt;First off, no pointer types derive from object, nor are any of them convertible to object. Unsafe pointer types are explicitly outside of the normal type rules for the language. (If you want to treat a pointer as a value type, convert it to System.IntPtr, and then you can use it as a value type.)&amp;nbsp;We'll leave pointer types aside for the rest of this discussion.&lt;/P&gt;
&lt;P&gt;A great many types do derive from object. All value types,&amp;nbsp;including enums and nullable types,&amp;nbsp;derive from object. All class, array and delegate types derive from object.&lt;/P&gt;
&lt;P&gt;These are all the "concrete" types; every object instance that you actually encounter in the wild will be either null, or a class, delegate, array, struct, enum or nullable value type. So it would be correct, though tautological, to say that all object instances derive from object. But that wasn't the myth; the myth stated was that all &lt;EM&gt;types&lt;/EM&gt; are derived from object. &lt;/P&gt;
&lt;P&gt;Interface types, not being classes, are not derived from object. They are all &lt;EM&gt;convertible&lt;/EM&gt; to object, to be sure, because we know that at runtime the instance will be a concrete type. But interfaces only derive from other interface types, and object is not an interface type.&lt;/P&gt;
&lt;P&gt;"Open" type parameter types are also not derived from object. They are, to be sure, types. You can make a field whose type is a type parameter type. And since generic types and methods ultimately are only ever used at runtime when fully "constructed" with "concrete" type arguments, type parameter types are always &lt;EM&gt;convertible&lt;/EM&gt; to object. (This is why you cannot make an IEnumerable&amp;lt;void*&amp;gt; -- we require that the type argument be convertible to object.) Type parameter types are not derived from anything; they have an "effective base class", so that type arguments are constrained to be derived from the effective base class, but they themselves are not "derived" from anything.&lt;/P&gt;
&lt;P&gt;The way to correct this myth is to simply replace "derives from" with "is convertible to", and to ignore pointer types: &lt;STRONG&gt;every non-pointer type in C# is &lt;EM&gt;convertible &lt;/EM&gt;to object.&lt;/STRONG&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9820268" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx">Value Types</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category></item><item><title>The Stack Is An Implementation Detail, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx</link><pubDate>Mon, 27 Apr 2009 16:15:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9549311</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>35</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9549311.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9549311</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A href="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_4.jpg" mce_href="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_4.jpg"&gt;&lt;IMG title="Stack&lt;Stone&gt;" style="BORDER-TOP-WIDTH: 0px; DISPLAY: inline; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; MARGIN-LEFT: 0px; MARGIN-RIGHT: 0px; BORDER-RIGHT-WIDTH: 0px" height=240 alt="Stack&lt;Stone&gt;" src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_thumb_1.jpg" width=156 align=left border=0 mce_src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/TheStackIsAnImplementationDetail_C978/Stack_thumb_1.jpg"&gt;&lt;/A&gt;I blogged a while back about how &lt;A href="http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx"&gt;“references” are often described as “addresses”&lt;/A&gt; when describing the semantics of the C# memory model. Though that’s arguably &lt;EM&gt;correct&lt;/EM&gt;, it’s also arguably an &lt;EM&gt;implementation detail&lt;/EM&gt; rather than an important eternal truth. Another memory-model implementation detail I often see presented as a fact is “value types are allocated on the stack”. I often see it because of course, &lt;A href="http://msdn.microsoft.com/en-us/library/system.valuetype.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.valuetype.aspx"&gt;that’s what our documentation says&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;Almost every article I see that describes the difference between value types and reference types explains in (frequently incorrect) detail about what “the stack” is and how the major difference between value types and reference types is that value types go on the stack. I’m sure you can find dozens of examples by searching the web.&lt;/P&gt;
&lt;P&gt;I find this characterization of a value type based on its &lt;EM&gt;implementation details&lt;/EM&gt; rather than its &lt;EM&gt;observable characteristics&lt;/EM&gt; to be both confusing and unfortunate. Surely the most relevant fact about value types is not the implementation detail of &lt;EM&gt;how they are allocated&lt;/EM&gt;, but rather the &lt;EM&gt;by-design semantic meaning&lt;/EM&gt; of “value type”, namely &lt;EM&gt;that they are always copied “by value”&lt;/EM&gt;. If the relevant thing was their allocation details then we’d have called them “heap types” and “stack types”. But that’s not relevant most of the time. Most of the time the relevant thing is their copying and identity semantics.&lt;/P&gt;
&lt;P&gt;I regret that the documentation does not focus on what is most relevant; by focusing on a largely irrelevant implementation detail, we enlarge the importance of that implementation detail and obscure the importance of what makes a value type semantically useful. I dearly wish that all those articles explaining what “the stack” is would instead spend time explaining what exactly “copied by value” means and how misunderstanding or misusing “copy by value” can cause bugs.&lt;/P&gt;
&lt;P&gt;Of course, the simplistic statement I described is not even &lt;EM&gt;true&lt;/EM&gt;. As the MSDN documentation correctly notes, value types are allocated on the stack &lt;EM&gt;sometimes&lt;/EM&gt;. For example, the memory for an integer field in a class type is part of the class instance’s memory, which is allocated on the heap. A local variable is hoisted to be implemented as a field of a hidden class if the local is an outer variable used by an anonymous method(*) so again, the storage associated with that local variable will be on the heap if it is of value type.&lt;/P&gt;
&lt;P&gt;But more generally, again we have &lt;STRONG&gt;an explanation that doesn’t actually explain anything&lt;/STRONG&gt;. Leaving performance considerations aside, what possible difference does it make &lt;EM&gt;to the developer&lt;/EM&gt; whether the CLR’s jitter happens to allocate memory for a particular local variable by adding some integer to the pointer that we call “the stack pointer” or adding the same integer to the pointer that we call “the top of the GC heap”? As long as the implementation maintains the semantics guaranteed by the specification, it can choose any strategy it likes for generating efficient code. &lt;/P&gt;
&lt;P&gt;Heck, there’s no requirement that the &lt;EM&gt;operating system&lt;/EM&gt; that the CLI is implemented on top of provide a per-thread one-meg array called “the stack”. That Windows typically does so, and that this one-meg array is an efficient place to store small amounts of short-lived data is great, but it’s not a requirement that an operating system provide such a structure, or that the jitter use it. The jitter could choose to put every local “on the heap” and live with the performance cost of doing so, as long as the value type semantics were maintained.&lt;/P&gt;
&lt;P&gt;Even worse though is the frequently-seen characterization that value types are “small and fast” and reference types are “big and slow”. Indeed, value types that can be jitted to code that allocates off the stack are extremely fast to both allocate and deallocate. Large structures heap-allocated structures like arrays of value type are also pretty fast, particularly if you need them initialized to the default state of the value type. And there is some memory overhead to ref types. And there are some high-profile cases where value types give a big perf win. &lt;STRONG&gt;But in the vast majority of programs out there, local variable allocations and deallocations are not going to be the performance bottleneck.&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;Making the nano-optimization of making a type that really should be a ref type into a value type for a few nanoseconds of perf gain is probably not worth it. I would only be making that choice if profiling data showed that there was a large, real-world-customer-impacting performance problem directly mitigated by using value types. Absent such data, I’d always make the choice of value type vs reference type based on whether the type is &lt;EM&gt;semantically&lt;/EM&gt; representing a value or &lt;EM&gt;semantically&lt;/EM&gt; a reference to something.&lt;/P&gt;
&lt;P&gt;UPDATE: &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx"&gt;Part two is here&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;*******&lt;/P&gt;
&lt;P&gt;(*) Or in an iterator block.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9549311" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Value+Types/default.aspx">Value Types</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/myths/default.aspx">myths</category></item></channel></rss>