<?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 : Code Generation</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx</link><description>Tags: Code Generation</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>The Purpose, Revealed</title><link>http://blogs.msdn.com/ericlippert/archive/2009/11/25/the-purpose-revealed.aspx</link><pubDate>Wed, 25 Nov 2009 17:03:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9928668</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9928668.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9928668</wfw:commentRss><description>&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;</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/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Software+development+methodology/default.aspx">Software development methodology</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_+4.0/default.aspx">C# 4.0</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/named+parameters/default.aspx">named parameters</category></item><item><title>The void is invariant</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/29/the-void-is-invariant.aspx</link><pubDate>Mon, 29 Jun 2009 17:30:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9756024</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>19</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9756024.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9756024</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;[UPDATES below]&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A while back I described &lt;A href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx"&gt;a kind of variance that we’ve supported since C# 2.0.&lt;/A&gt; When assigning a method group to a delegate type, such that both the selected method and the delegate target agree that their return type is a reference type, then the conversion is allowed to be covariant. That is, you can say:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Giraffe GetGiraffe() { … }&lt;BR&gt;…&lt;BR&gt;Func&amp;lt;Animal&amp;gt; f = GetGiraffe;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This works logically because anyone who calls f must be able to handle any animal that comes back. The actual method claims to only return animals, and in fact, makes the stronger claim to only return giraffes. &lt;/P&gt;
&lt;P&gt;This works out in the CLR because the bits that make up a reference to an instance of Giraffe are exactly the same bits that make up a reference to that Giraffe interpreted as an instance of Animal. We can allow this magical conversion to happen because the CLR guarantees that it will all just work out without going in there and having to futz around with the bits.&lt;/P&gt;
&lt;P&gt;This is why this trick only works with reference types. A method that returns, say, a double cannot be converted via a covariant conversion to a delegate type that expects the method to return an object. Somewhere there would have to be code emitted that takes the returned double and boxes it to object; the bits of a double and the bits of a reference to an object boxing a double are completely different.&lt;/P&gt;
&lt;P&gt;But why doesn’t this trick work with void types? Here we have a method that returns some sort of success or failure code. Maybe we don’t care what it returns.&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static bool DoSomething(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; if (b) return DoTheThing();&lt;BR&gt;&amp;nbsp; else return DoTheOtherThing();&lt;BR&gt;}&lt;/P&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;This doesn’t work. Why not? The caller of the action is not even going to &lt;EM&gt;use&lt;/EM&gt; the returned value, so it doesn’t matter one bit what it is! Shouldn’t “void” be considered &lt;EM&gt;a supertype of all possible types&lt;/EM&gt; for the purposes of covariant return type conversions from method groups to delegate types?&lt;/P&gt;
&lt;P&gt;No, and I’ll tell you why.&lt;/P&gt;
&lt;P&gt;Consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;bool x = DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the following:&lt;/P&gt;
&lt;P&gt;(1) put true on the IL stack – the stack gets one deeper&lt;BR&gt;(2) call DoSomething – the argument is removed from the stack and the return value is placed on the stack.&amp;nbsp; Net, the stack stays the same size as before&lt;BR&gt;(3) stuff whatever on top of the stack into local variable x – the stack now returns to its original depth.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;DoSomething(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We spit out IL that does the first two steps as before. But we cannot stop there! There is now a bool on the IL stack which needs to be removed. We generate a pop instruction to represent the fact that the returned bool has been discarded.&lt;/P&gt;
&lt;P&gt;Now consider what happens when you do this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;action(true);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The compiler believes that action is a void-returning method, so it does not generate a pop instruction. If we allowed you to stuff DoSomething into the action, then we would be allowing you to misalign the IL stack!&lt;/P&gt;
&lt;P&gt;But didn’t I say “&lt;A 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;the stack is an implementation detail?&lt;/A&gt;” Yes, but &lt;EM&gt;that’s a different stack&lt;/EM&gt;. The CLI specification describes a “virtual machine” which passes around arguments and returned values on a stack. An implementation of the CLI is required to make something that behaves like the specified machine, but it is not required to do so in any particular manner. It is not required to use the million-bytes-per-thread stack supplied to each thread by the operating system as its implementation of the IL stack; that’s a convenient structure to use, of course, but it’s an implementation detail that it does so.&lt;/P&gt;
&lt;P&gt;(As an aside: when we implemented the script engines, we also first specified our own private stack-based virtual machine. When we implemented it, we decided to put the information about “return addresses” – that is, “what code do I run next?” on the system stack, but we put arguments and return values of script functions in a stack-shaped block of memory that we allocated on our own. This made building the JScript garbage collector easier.)&lt;/P&gt;
&lt;P&gt;In practice, the jitter uses the system stack for some things and registers for other things. Return values are actually often sent back in a register, not on the stack. But that implementation detail doesn’t help us out when deciding what the conversion rules are; we have to assume that the implementation can do no more than what the CLI specification says. Had the CLI specification said “the returned value of any function is passed back in a ‘virtual register’” rather than having it pushed onto the stack, then we could have made void-returning delegates compatible with functions that returned anything. You can always just ignore the value in the register. But that’s not what the CLI specified, so that’s not what we can do. &lt;/P&gt;
&lt;P&gt;[UPDATE]&lt;/P&gt;
&lt;P&gt;A number of people have asked in the comments why we do not simply generate a helper method that does what you want. That is, when you say&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;Action&amp;lt;bool&amp;gt; action = DoSomething;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;realize that as&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;static&amp;nbsp;void DoSomethingHelper(bool b)&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp; bool result = DoSomething(b); // result is ignored&lt;BR&gt;}&lt;BR&gt;...&lt;BR&gt;Action&amp;lt;bool&amp;gt; action = DoSomethingHelper;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We could do that. But where would you like the line to be drawn? Should you be able to assign a&amp;nbsp;reference to a method that returns an int to a Func&amp;lt;Nullable&amp;lt;int&amp;gt;&amp;gt;? We could spit a helper method that converts the int to a nullable int.&amp;nbsp;What about Func&amp;lt;double&amp;gt;? We could spit a helper method that converts the int to a double. What about Func&amp;lt;object&amp;gt;? We could spit a helper method that boxes the int, unexpectedly allocating memory off the heap every time you call it. What about a Func&amp;lt;Foo&amp;gt; where there is a user-defined implicit conversion from int to Foo?&lt;/P&gt;
&lt;P&gt;We could be spitting arbitrarily complex fixer-upper methods that would seamlessly "do what you meant to say", and we have to stop somewhere.&amp;nbsp;The exact semantics of what we&amp;nbsp;do and do not&amp;nbsp;fix up would have to be designed, specified, implemented, tested, documented, shipped to customers and maintained forever. Those are costs. Plus, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/31/future-breaking-changes-part-two.aspx"&gt;every time we add a new conversion rule to the language we add breaking changes&lt;/A&gt;. The costs of those breaking changes to our customers have to be factored in.&lt;/P&gt;
&lt;P&gt;But more fundamentally, one of the design principles of C# is "if &lt;STRONG&gt;you say something wrong then &lt;EM&gt;we tell you&lt;/EM&gt; rather than trying &lt;EM&gt;to guess what you meant&lt;/EM&gt;&lt;/STRONG&gt;". JScript is deliberately a "muddle on through and do the best you can" language; C# is not. If what you want to do is make a delegate to a helper method then you express that intention by going right ahead and making that method.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9756024" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</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/Breaking+Changes/default.aspx">Breaking Changes</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/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Memory+Management/default.aspx">Memory Management</category></item><item><title>What does the optimize switch do?</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/11/what-does-the-optimize-switch-do.aspx</link><pubDate>Thu, 11 Jun 2009 16:57:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9685964</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>39</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9685964.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9685964</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I was asked recently exactly what optimizations the C# compiler performs when you specify the optimize switch. Before I answer that, I want to make sure that something is perfectly clear. The compiler’s “usage” string is not lying when it says:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;/debug[+|-]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Emit debugging information&lt;BR&gt;/optimize[+|-]&amp;nbsp; Enable optimizations &lt;/SPAN&gt;
&lt;P&gt;Emitting debug information and optimizing the generated IL are orthogonal; they have no effect on each other at all (*). The &lt;EM&gt;usual&lt;/EM&gt; thing to do is to have debug on and optimizations off, or vice versa, but the other two combinations are perfectly legal. (And while I’m at it, turning debug information generation on does not also do /d:DEBUG; that’s also orthogonal. Again, the sensible thing to do is to keep /debug and /d:DEBUG in sync, but you do not have to; you might want to debug the optimized version without assertions and we’re not going to stop you.)&lt;/P&gt;
&lt;P&gt;From this point on, when I say “emitting” I mean “producing metadata”, and when I say “generating” I mean “producing IL”.&lt;/P&gt;
&lt;P&gt;So, first off, there are some optimizations that the compiler always performs, regardless of the optimize flag.&lt;/P&gt;
&lt;P&gt;The language semantics require us to do constant folding because we need to detect that this is an error:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;switch(x) { &lt;BR&gt;case 2:&lt;BR&gt;case 1+1:&lt;BR&gt;…&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The compiler will replace usages of constant fields with the constant, but does not perform any more sophisticated &lt;A href="http://en.wikipedia.org/wiki/Constant_propagation" mce_href="http://en.wikipedia.org/wiki/Constant_propagation"&gt;constant propagation&lt;/A&gt;, even though the compiler has a reachability analyzer. &lt;/P&gt;
&lt;P&gt;Speaking of which, there are two kinds of reachability analysis we perform for &lt;A href="http://en.wikipedia.org/wiki/Dead_code_elimination" mce_href="http://en.wikipedia.org/wiki/Dead_code_elimination"&gt;dead code elimination&lt;/A&gt;. First, there is the “according to spec” reachability. The specification calls out that reachability analysis consumes compile-time constants. This is the reachability analysis we use to give “unreachable code” warnings, to determine whether local variables are definitely assigned on all code paths, and to determine whether the end point of a non-void method is reachable. If this first pass determines that code is unreachable then we never generate IL for it. For example, this is optimized away:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;if (false) M();&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;But if the expression involves non-compile-time constants then this first form of reachability analysis would tell you that the call to N here is reachable, and therefore is a definite assignment error:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int x = M();&lt;BR&gt;int y;&lt;BR&gt;if (x * 0 != 0) N(y);&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;If you fixed that up so that y was definitely assigned, then the first-pass reachability analyzer would NOT trim this code because it still thinks that the call is reachable.&lt;/P&gt;
&lt;P&gt;But clearly you and I know that the call is not reachable, because we know more about arithmetic than the specified reachability analyzer. We perform a second pass of reachability analysis during code generation which is much smarter about these things. We can do that because the second pass only affects codegen, it does not affect language semantics, error reporting, and so on.&lt;/P&gt;
&lt;P&gt;The existence of that second pass implies that we do a simple arithmetic optimizations on expressions which are only partially constant. For example, if you have a method M that returns an integer, then code like &lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;if (M() * 0 == 0) N();&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;can be generated as though you’d written just:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;M();&lt;BR&gt;N();&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;We have lots of simple number and type algebra optimizers that look for things like adding zero to an integer, multiplying integers by one, using “null” as an argument to “is” or “as”, concatenation of literal strings, and so on. The expression optimizations always happen, whether you’ve set the optimize flag or not; whether basic blocks that are determined to be unreachable after those optimizations are trimmed depends on the flag.&lt;/P&gt;
&lt;P&gt;We also perform some small optimizations on some call sites and null checks. (Though &lt;A href="http://stackoverflow.com/questions/946999/curious-c-using-statement-expansion" mce_href="http://stackoverflow.com/questions/946999/curious-c-using-statement-expansion"&gt;not as many as we could&lt;/A&gt;.) For example, suppose you have a non-virtual instance method M on a reference type C, and a method&amp;nbsp;GetC that returns a C. If you say GetC().M() then we generate a callvirt instruction to call M. Why? Because it is &lt;EM&gt;legal&lt;/EM&gt; to generate a callvirt for an instance method on a reference type, and callvirt automatically inserts a null check. The non-virtual call instruction does not do a null check; we'd have to generate extra code to check whether GetC returns null. So that's a small code size optimization. But we can do even better than that; if you have (new C()).M(), we generate a call instruction because we know that the result of&amp;nbsp;the "new" operator is never null. That gives us a small time optimization because we can skip the nanosecond it takes to do the null check. Like I said, it's a small optimization. &lt;/P&gt;
&lt;P&gt;The /optimize flag does not change a huge amount of our emitting and generation logic. We try to always generate straightforward, verifiable code and then rely upon the jitter to do the heavy lifting of optimizations when it generates the real machine code. But we will do some simple optimizations with that flag set. For example, with the flag set:&lt;/P&gt;
&lt;P&gt;* Expressions which are determined to be only useful for their side effects are turned into code that merely produces the side effects.&lt;/P&gt;
&lt;P&gt;* We omit generating code for things like &lt;SPAN class=code&gt;int foo = 0;&lt;/SPAN&gt; because we know that the memory allocator will initialize fields to default values.&lt;/P&gt;
&lt;P&gt;* We omit emitting and generating empty static class constructors. (Which typically happens if the static constructor set all the fields to their default value and the previous optimization eliminated all of them.)&lt;/P&gt;
&lt;P&gt;* We omit emitting a field for any hoisted locals that are unused in an iterator block. (This includes that case where the local in question is used only inside an anonymous function in the iterator block, in which case it is going to become hoisted into a field of the closure class for the anonymous function. No need to hoist it twice if we don’t need to.)&lt;/P&gt;
&lt;P&gt;* We attempt to minimize the number of local variable and temporary slots allocated. For example, if you have:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;for (int i = …)&amp;nbsp; {…}&lt;BR&gt;for (int&amp;nbsp;i = …) {…}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;then the compiler could generate code to re-use the local variable storage reserved for i when the second i comes along. (We eschew this optimization if the locals have different names because then it gets hard to emit sensible debug info, which we still want to do even for the optimized build. However, the jitter is free to perform this optimization if it wishes to.)&lt;/P&gt;
&lt;P&gt;* Also, if you have a local which is never used at all, then there is no storage allocated for it if the flag is set.&lt;/P&gt;
&lt;P&gt;* Similarly, the compiler is more aggressive about re-using the unnamed temporary slots sometimes used to store results of subexpression calculations.&lt;/P&gt;
&lt;P&gt;* Also, with the flag set the compiler is more aggressive about generating code that throws away “temporary” values quickly for things like controlling variables of switch statements, the condition in an “if” statement, the value being returned, and so on. &lt;A href="http://stackoverflow.com/questions/944443/what-are-these-opcodes-for" mce_href="http://stackoverflow.com/questions/944443/what-are-these-opcodes-for"&gt;In the non-optimized build these values are treated as unnamed local variables, loaded from and stored to specific locations.&lt;/A&gt; In the optimized build they can often be just kept on the stack proper.&lt;/P&gt;
&lt;P&gt;* We eliminate pretty much all of the “breakpoint convenience” no-ops.&lt;/P&gt;
&lt;P&gt;* If&amp;nbsp;a try block is empty then&amp;nbsp;clearly the catch blocks are not reachable and can be trimmed. (Finally blocks of empty tries are preserved as protected regions because they have unusual behaviour when faced with&amp;nbsp;certain exceptions; see the comments for details.)&amp;nbsp;&lt;/P&gt;
&lt;P&gt;* If we have an instruction which branches to LABEL1, and the instruction at LABEL1 branches to LABEL2, then we rewrite the first instruction as a branch straight to LABEL2. Same with branches that go to returns.&lt;/P&gt;
&lt;P&gt;* We look for “branch over a branch” situations.&amp;nbsp;For example, here we go to LABEL1 if condition is false, otherwise we go to LABEL2. &lt;SPAN class=code&gt;&lt;BR&gt;&lt;BR&gt;brfalse condition, LABEL1 &lt;BR&gt;br&amp;nbsp;LABEL2&lt;BR&gt;LABEL1: somecode&lt;BR&gt;&lt;BR&gt;&lt;/SPAN&gt;Since we are simply branching over another branch, we can rewrite this as simply "if condition is true, go to LABEL2":&lt;/P&gt;&lt;SPAN class=code&gt;brtrue condition, LABEL2&lt;BR&gt;somecode&lt;BR&gt;&lt;/SPAN&gt;
&lt;P&gt;* We look for “branch to nop” situations. If a branch goes to a nop then you can make it branch to the instruction after the nop.&lt;/P&gt;
&lt;P&gt;* We look for “branch to next” situations; if a branch goes to the next instruction then you can eliminate it.&lt;/P&gt;
&lt;P&gt;* We look for two return instructions in a row; this happens sometimes and obviously we can turn it into a single return instruction.&lt;/P&gt;
&lt;P&gt;That’s pretty much it. These are very straightforward optimizations; there’s no inlining of IL, no loop unrolling, no interprocedural analysis whatsoever. We let the jitter team worry about optimizing the heck out of the code when it is actually spit into machine code; that’s the place where you can get real wins. &lt;/P&gt;
&lt;P&gt;*******&lt;/P&gt;
&lt;P&gt;(*) A small lie. There is some interaction between the two when we generate the attributes that describe whether the assembly&amp;nbsp;is Edit’n’Continuable during debugging. &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9685964" 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/Code+Generation/default.aspx">Code Generation</category></item><item><title>The Stack Is An Implementation Detail, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx</link><pubDate>Mon, 04 May 2009 20:57:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9586162</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>20</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9586162.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9586162</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;A number of people have asked me, in the wake of my earlier posting about value types being on the stack, &lt;em&gt;why&lt;/em&gt; it is that value types go on the stack but reference types do not.&lt;/p&gt; &lt;p&gt;The short answer is “because they can”. And since the stack is &lt;em&gt;cheap&lt;/em&gt;, we &lt;em&gt;do&lt;/em&gt; put them on the stack when possible.&lt;/p&gt; &lt;p&gt;The long answer is… long.&lt;/p&gt; &lt;p&gt;I’ll need to give a high-level description of the memory management strategies that we call “stack” and “heap”. Heap first.&lt;/p&gt; &lt;p&gt;The CLRs garbage-collected heap is a marvel of engineering with a huge amount of detail; this sketch is not actually how it works, but it’s a good enough approximation to get the idea. &lt;/p&gt; &lt;p&gt;The idea is that there is a large block of memory reserved for instances of reference types. This block of memory can have “holes” – some of the memory is associated with “live” objects, and some of the memory is free for use by newly created objects. Ideally though we want to have all the allocated memory bunched together and a large section of “free” memory at the top.&lt;/p&gt; &lt;p&gt;If we’re in that situation when new memory is allocated then the “high water mark” is bumped up, eating up some of the previously “free” portion of the block. The newly-reserved memory is then usable for the reference type instance that has just been allocated. That is &lt;em&gt;extremely cheap&lt;/em&gt;; just a single pointer move, plus zeroing out the newly reserved memory if necessary.&lt;/p&gt; &lt;p&gt;If we have holes then we can maintain a “free list” – a linked list of holes. We can then search the free list for a hole of appropriate size and fill it in. This is a bit more expensive since there is a list search. We want to avoid this suboptimal situation if possible.&lt;/p&gt; &lt;p&gt;When a garbage collection is performed there are three phases: mark, sweep and compact. In the “mark” phase, we assume that everything in the heap is “dead”. The CLR knows what objects were “guaranteed alive” when the collection started, so those guys are marked as alive. Everything they refer to is marked as alive, and so on, until the transitive closure of live objects are all marked. In the “sweep” phase, all the dead objects are turned into holes. In the “compact” phase, the block is reorganized so that it is one contiguous block of live memory, free of holes.&lt;/p&gt; &lt;p&gt;This sketch is complicated by the fact that there are actually &lt;em&gt;three&lt;/em&gt; such arenas; the CLR collector is &lt;em&gt;generational&lt;/em&gt;. Objects start off in the “short lived” heap. If they survive they eventually move to the “medium lived” heap, and if they survive there long enough, they move to the “long lived” heap. The GC runs very often on the short lived heap and very seldom on the long lived heap; the idea is that we do not want to have the expense of constantly re-checking a long-lived object to see if it is still alive. But we also want short-lived objects to be reclaimed swiftly.&lt;/p&gt; &lt;p&gt;The GC has a huge amount of carefully tuned policy that ensures high performance; it attempts to balance the memory and time costs of having a Swiss-cheesed heap against the high cost of the compaction phase. Extremely large objects are stored in a special heap that has different compaction policy. And so on. I don’t know all the details, and fortunately, I don’t need to. (And of course, I have left out lots of additional complexity that is not germane to this article – pinning and finalization and weak refs and so on.)&lt;/p&gt; &lt;p&gt;Now compare this to the stack. The stack is like the heap in that it is a big block of memory with a “high water mark”. But what makes it a “stack” is that the memory on the bottom of the stack always lives longer than the memory on the top of the stack; the stack is strictly ordered. The objects that are going to die first are on the top, the objects that are going to die last are on the bottom. And with that guarantee, we know that the stack will never have holes, and therefore will not need compacting. We know that the stack memory will always be “freed” from the top, and therefore do not need a free list. We know that anything low-down on the stack is guaranteed alive, and so we do not need to mark or sweep.&lt;/p&gt; &lt;p&gt;On a stack, the allocation is just a single pointer move – the same as the best (and typical) case on the heap. But because of all those guarantees, the deallocation is also a single pointer move! And &lt;em&gt;that&lt;/em&gt; is where the huge time performance savings is. A lot of people seem to think that heap allocation is expensive and stack allocation is cheap. They are actually about the same, typically. It’s the deallocation costs – the marking and sweeping and compacting and moving memory from generation to generation – that are massive for heap memory compared to stack memory.&lt;/p&gt; &lt;p&gt;Clearly it is better to use a stack than a GC heap if you can. When can you? Only when you can guarantee that all the necessary conditional that make a stack work are actually achieved. Local variables and formal parameters of value type are the sweet spot that achieve that. The locals of frames on the bottom of the stack clearly live longer than the locals on the frames of the top of the stack. Locals of value type are copied by value, not by reference, so the local is the only thing that references the memory; there is no need to track who is referencing a particular value to determine its lifetime. And the only way to take a ref to a local is to pass it as a ref or out parameter, which just passes the ref on &lt;u&gt;up&lt;/u&gt; the stack. The local is going to be alive anyway, so the fact that there is a ref to it “higher up” the call stack doesn’t change its lifetime.&lt;/p&gt; &lt;p&gt;aside &lt;br&gt;{ &lt;/p&gt; &lt;p&gt;A few asides:&lt;/p&gt; &lt;p&gt;This explains why you cannot make a “ref int” field. If you could then you could &lt;em&gt;store&lt;/em&gt; a ref to the value of a short-lived local inside a long-lived object. Were that legal then using the stack as a memory management technique would no longer be a viable optimization; value types would be just another kind of reference type and would have to be garbage collected.&lt;/p&gt; &lt;p&gt;Anonymous function closures and iterator block closures are implemented behind-the-scenes by turning locals and formal parameters into fields. So now you know why it is illegal to capture a ref or out formal parameter in an anonymous function or iterator block; doing so would not be a legal field. &lt;/p&gt; &lt;p&gt;Of course we do not want to have ugly and bizarre rules in the language like “you can close over any local or value parameter &lt;em&gt;but not a ref or out parameter&lt;/em&gt;”. But because we want to be able to get the optimization of putting value types on the stack, we have chosen to put this odd restriction into the language. Design is, as always, the art of finding compromises. &lt;/p&gt; &lt;p&gt;Finally, the CLR &lt;em&gt;does&lt;/em&gt; allow “ref return types”; you could in theory have a method “ref int M() { … }” that returned a reference to an integer variable. If for some bizarre reason we ever decided to allow that in C#, we’d have to fix up the compiler and verifier so that they ensured that it was only possible to return refs to variables that were known to be on the heap, or known to be “lower down” on the stack than the callee.&lt;/p&gt; &lt;p&gt;}&lt;/p&gt; &lt;p&gt;So there you go. Local variables of value type go on the stack because they can. They can because (1) “normal” locals have strict ordering of lifetime, and (2) value types are always copied by value and (3) it is illegal to store a reference to a local anywhere that could live longer than the local. By contrast, reference types have a lifetime based on the number of living references, are copied by reference, and those references can be stored anywhere. &lt;strong&gt;The additional flexibility that reference types give you comes at the cost of a much more complex and expensive garbage collection strategy.&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;But again, all of this is an implementation detail. Using the stack for locals of value type is just an optimization that the CLR performs on your behalf. The relevant feature of value types is &lt;strong&gt;that they have the semantics of being copied by value&lt;/strong&gt;, not that &lt;strong&gt;sometimes their deallocation can be optimized by the runtime&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9586162" 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/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></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><item><title>Representation and Identity</title><link>http://blogs.msdn.com/ericlippert/archive/2009/03/19/representation-and-identity.aspx</link><pubDate>Thu, 19 Mar 2009 16:46:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9488368</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>23</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9488368.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9488368</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;I get a fair number of questions about the C# cast operator. The most frequent question I get is:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;short sss = 123;&lt;BR&gt;object ooo = sss;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Box the short.&lt;BR&gt;int iii = (int) sss;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Perfectly legal.&lt;BR&gt;int jjj = (int) (short) ooo; // Perfectly legal&lt;BR&gt;int kkk = (int) ooo;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Invalid cast exception?! Why?&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Why? Because a boxed T can only be unboxed to T. (*) Once it is unboxed, it’s just a value that can be cast as usual, so the double cast works just fine. &lt;/P&gt;
&lt;P&gt;Many people find this restriction grating; they expect to be able to cast a boxed thing to &lt;EM&gt;anything&lt;/EM&gt; that the unboxed thing could have been cast to. There are ways to do that, as we’ll see, but there are good reasons why the cast operator does what it does.&lt;/P&gt;
&lt;P&gt;To understand why this design works this way it’s necessary to first wrap your head around the contradiction that is the cast operator. There are two (¤) basic usages of the cast operator in C#:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;My code has an expression of type B, but I happen to have more information than the compiler does. I claim to know for certain that at runtime, &lt;STRONG&gt;this object of type B will actually always be of derived type D&lt;/STRONG&gt;. I will inform the compiler of this claim by inserting a cast to D on the expression. Since the compiler probably cannot verify my claim, the compiler might ensure its veracity by inserting a run-time check at the point where I make the claim. If my claim turns out to be inaccurate, the CLR will throw an exception.&lt;BR&gt;
&lt;LI&gt;I have an expression of some type T which &lt;STRONG&gt;I know for certain is not of type U&lt;/STRONG&gt;. However, I have a well-known way of associating some or all values of T with an “equivalent” value of U. I will instruct the compiler to generate code that implements this operation by inserting a cast to U. (And if at runtime there turns out to be no equivalent value of U for the particular T I’ve got, again we throw an exception.)&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;The attentive reader will have noticed that these are &lt;EM&gt;opposites&lt;/EM&gt;. A neat trick, to have an operator which means two contradictory things, don’t you think?&lt;/P&gt;
&lt;P&gt;This dichotomy motivates yet another classification scheme for conversions (†).&amp;nbsp; We can divide conversions into &lt;STRONG&gt;representation-preserving conversions&lt;/STRONG&gt; (B to D) and &lt;STRONG&gt;representation-changing conversions&lt;/STRONG&gt; (T to U). (‡) We can think of representation-preserving conversions on reference types as those conversions which &lt;EM&gt;preserve the identity of the object&lt;/EM&gt;. When you cast a B to a D, you’re not doing anything to the existing object; you’re merely &lt;EM&gt;verifying&lt;/EM&gt; that it is actually the type you say it is, and moving on. The identity of the object and&amp;nbsp;the bits which represent the&amp;nbsp;reference&amp;nbsp;stay the same. But when you cast an int to a double, the resulting bits are very different. &lt;/P&gt;
&lt;P&gt;All the built-in reference conversions are identity-preserving (£). Obviously trivial “conversions” such as converting from int to int are also representation-preserving conversions. All user-defined conversions (§) and non-trivial value type conversions (such as converting from int to double) are representation-changing conversions. Boxing and unboxing conversions are all representation-changing conversions.&lt;/P&gt;
&lt;P&gt;The representation-preserving conversions that are known to never fail often result in no codegen at all (₪). If a representation-preserving conversion could fail then a castclass instruction is emitted, which does a runtime check and throws if the check fails. &lt;/P&gt;
&lt;P&gt;But each representation-changing conversion is handled in its own special way. User-defined conversions are resolved using a special version of the overload resolution algorithm, and generated as a call to the appropriate static method. Boxing and unboxing conversions are generated as box and unbox instructions. All the other built-in conversions (int to double, and so on) are generated as &lt;STRONG&gt;custom sequences of instructions&lt;/STRONG&gt; that do the right conversion.&lt;/P&gt;
&lt;P&gt;So now that you know that, consider what the compiler would have to do to make this work the way some people expect:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;int kkk = (int) ooo; &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;All that the compiler knows is that ooo is of type object. It could be &lt;EM&gt;anything&lt;/EM&gt;. Suppose it is a boxed int – then the compiler should generate an unboxing instruction. Suppose it is a boxed short. Then the compiler should unbox the short and then generate the custom sequence of instructions that convert a short to an&amp;nbsp;int. Suppose it is a boxed double – same thing, but different instructions. And so on, for all the built-in conversions that go to integer.&lt;/P&gt;
&lt;P&gt;This would be a huge amount of code to generate, and it would be very slow. The code is of course so large that you would want to put it in its own method and just generate a call to it. Rather than do that by default, and always generate code that is slow, large and fragile, instead we’ve decided that unboxing can only unbox to the exact type. If you want to call the slow method that does all that goo, it’s available – you can always call Convert.ToInt32, which does all that analysis at runtime for you. We give you the choice between “fast and precise” or “slow and lax”, and &lt;EM&gt;the sensible default is the former&lt;/EM&gt;. If you want the latter then call the method.&lt;/P&gt;
&lt;P&gt;That’s just the built-in conversions. Let’s continue imagining what would have to happen if we wanted &lt;EM&gt;all possible conversions&lt;/EM&gt; to int to just work out correctly at runtime, instead of just bailing out early if the boxed thing is not an int.&lt;/P&gt;
&lt;P&gt;Suppose the object is a Foo where there is a user-defined conversion from Foo (or one of its base classes) to int (or a type implicitly convertible to int, like, say, Nullable&amp;lt;int&amp;gt;). Then the compiler would need to generate a call to that conversion method, just as it would if the type had been known at compile time, and then possibly also generate the conversion from the return type of the method to int.&lt;/P&gt;
&lt;P&gt;Remember, there could be arbitrarily many such conversion methods on arbitrarily many types. The type Foo and its conversion method&amp;nbsp;might not even be defined in the assembly currently&amp;nbsp;being compiled or any assembly referenced. Therefore the compiler would have to generate code to interrogate Foo at runtime, do the overload resolution analysis, and then dynamically spit the code to do the call.&lt;/P&gt;
&lt;P&gt;Which is exactly what the compiler does in C# 4.0 if the argument to the cast is of type “dynamic” instead of object. &lt;EM&gt;The compiler actually generates code which starts a mini version of the compiler up again at runtime, does all that analysis, and spits fresh code&lt;/EM&gt;. This is not &lt;EM&gt;fast&lt;/EM&gt;, but it is &lt;EM&gt;accurate&lt;/EM&gt;, if that’s what you really need. (And the spit code is then cached so that the next time this call site is hit, it is much faster.)&lt;/P&gt;
&lt;P&gt;I don’t think people &lt;EM&gt;really&lt;/EM&gt; expect the compiler to start up again at runtime every time they cast an object to int; I think they just haven’t thought through carefully exactly how much analysis solving the problem would take. Rather a lot, it turns out.&lt;/P&gt;
&lt;P&gt;*************&lt;/P&gt;
&lt;P&gt;(*) Or Nullable&amp;lt;T&amp;gt;.&lt;/P&gt;
&lt;P&gt;(¤) There are others that are not germane to this discussion. For example, a third usage is “Everyone knows that this D is also of base type B; I want the compiler to treat this expression of type D as a B for overload resolution purposes.” That would clearly be an identity-preserving conversion.&lt;/P&gt;
&lt;P&gt;(†) There are many ways to classify conversions; we already divide conversions into implicit/explicit, built-in/user-defined, and so on. For the purposes of this discussion we’ll gloss over the details of those other classifications.&lt;/P&gt;
&lt;P&gt;(‡) I’m glossing over here that certain conversions that the C# compiler thinks of as representation-changing are actually seen by the CLR verifier as representation-preserving. For example, the conversion from int to uint is seen by the CLR as representation-preserving because the 32 bits of a signed integer can be reinterpreted as an unsigned integer without changing the bits. These cases can be subtle and complex, and often have an impact on covariance-related issues; see next footnote.&lt;/P&gt;
&lt;P&gt;I’m also ignoring conversions involving generic type parameters which are not known at compile time to be reference or value types. There are special rules for classifying those which would be major digressions to get into.&lt;/P&gt;
&lt;P&gt;(£) This is why covariant and contravariant conversions of interface and delegate types require that all varying type arguments be of reference types. &lt;STRONG&gt;To ensure that a variant reference conversion is always identity-preserving, all of the conversions involving type arguments must also be identity-preserving.&lt;/STRONG&gt; The easiest way to ensure that all the non-trivial conversions on type arguments are identity-preserving is to restrict them to be reference conversions.&lt;/P&gt;
&lt;P&gt;(§) The rules of C# prohibit all user-defined conversions that could possibly be identity-preserving coercions. More generally, all user-defined conversions that could possibly be any "standard" conversion are illegal.&lt;/P&gt;
&lt;P&gt;(₪) Again, I’m ignoring irksome&amp;nbsp;generic issues here. There are situations where humans can prove mathematically that two generic type parameters must be identical at runtime, but the verifier is not smart enough to make those same deductions and requires the compiler to emit type checks.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9488368" 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/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Conversions/default.aspx">Conversions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx">Covariance and Contravariance</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Language+Design/default.aspx">Language Design</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/cast+operator/default.aspx">cast operator</category></item><item><title>Subtleties of C# IL codegen</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/17/subtleties-of-c-il-codegen.aspx</link><pubDate>Fri, 17 Aug 2007 19:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4432044</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>23</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/4432044.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=4432044</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;It must be CLR week over at &lt;A class="" href="http://blogs.msdn.com/oldnewthing/" mce_href="http://blogs.msdn.com/oldnewthing/"&gt;The Old New Thing&lt;/A&gt; because it's been non-stop posts about C# lately.&amp;nbsp;Raymond's last two technical posts have been about &lt;A class="" href="http://blogs.msdn.com/oldnewthing/archive/2007/08/16/4407029.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2007/08/16/4407029.aspx"&gt;null checks&lt;/A&gt; and &lt;A class="" href="http://blogs.msdn.com/oldnewthing/archive/2007/08/17/4422794.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2007/08/17/4422794.aspx"&gt;no-op instructions&lt;/A&gt; generated by the jitter when translating IL into machine code.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I'll comment on both posts here, but I want to get the no-op discussion done first, because there are some subtleties here I believe that Raymond's statement that the jitter does not generate no-ops when not debugging is not entirely correct. This is not a mere nitpick -- as we'll see, whether it does so or not actually has semantic relevance in rare stress cases.&lt;/P&gt;
&lt;P&gt;Now, I'll slap a disclaimer of my own on here: I know way more about the compiler than the jitter/debugger interaction. This is &lt;EM&gt;my&lt;/EM&gt; understanding of how it works. If someone who actually works on the jitter would like to confirm my and Raymond's interpretation of what we see going on here, I'd welcome that.&lt;/P&gt;
&lt;P&gt;Before I get into the details, let me point out that in the C# compiler, "debug info emitting on/off" and "IL optimizations on/off" are &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2005/10/28/483905.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2005/10/28/483905.aspx"&gt;orthogonal&lt;/A&gt; settings. One controls whether debug info is emitted, the other controls what IL the code generator spits out. It is sensible to set them as opposites but you certainly do not have to.&lt;/P&gt;
&lt;P&gt;With optimizations off, the C# compiler emits no-op IL instructions all over the place.&amp;nbsp; With debug info on and optimizations off, some of those no-ops will be there to be targets of breakpoints for statements or fragments of expressions which would otherwise be hard to put a breakpoint on. &lt;/P&gt;
&lt;P&gt;The jitter then cheerfully turns IL no-ops into x86 no-ops. &lt;EM&gt;I suspect that it does so whether there is a debugger attached or not&lt;/EM&gt;. &lt;/P&gt;
&lt;P&gt;Furthermore, I have not heard that the jitter ever manufactures no-ops out of whole cloth &lt;EM&gt;for debugging purposes&lt;/EM&gt;, as Raymond implies. I suspect -- but I have not verified -- that if you compile your C# program with debug info on AND optimizations on, then you'll see a lot fewer no-ops in the jitted code (and your debugging experience will be correspondingly worse). The jitter may of course generate no-ops for other purposes -- padding code out to word boundaries, etc.&lt;/P&gt;
&lt;P&gt;Now we come to the important point: &lt;STRONG&gt;It is emphatically NOT the case that a no-op cannot affect the behaviour of a program, as many people incorrectly believe.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In C#, &lt;SPAN class=code&gt;lock(expression) statement&lt;/SPAN&gt; is a syntactic sugar for something like&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;temp = expression;&lt;BR&gt;System.Threading.Monitor.Enter(temp); &lt;BR&gt;try { statement } finally { System.Threading.Monitor.Exit(temp); } &lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;The x86 jitter has the nice property that the code it generates guarantees that an exception is never thrown between the &lt;SPAN class=code&gt;Enter&lt;/SPAN&gt; and the &lt;SPAN class=code&gt;try&lt;/SPAN&gt;. This means that the &lt;SPAN class=code&gt;finally&lt;/SPAN&gt; always executes if the lock has been taken, which means that the locked resource is always unlocked. &lt;/P&gt;
&lt;P&gt;That is, unless the C# compiler generates a no-op IL instruction between the &lt;SPAN class=code&gt;Enter&lt;/SPAN&gt; and the &lt;SPAN class=code&gt;try&lt;/SPAN&gt;! The jitter turns that into a no-op x86 instruction, and it is possible for another thread to cause a thread abort exception while the thread that just took the lock is in the no-op. This is a long-standing bug in C# which we will unfortunately not be fixing for C# 3.0.&lt;/P&gt;
&lt;P&gt;If the scenario I've described happens then the &lt;SPAN class=code&gt;finally&lt;/SPAN&gt; will never be run, the lock will never be released and hey, now we're just begging for a deadlock.&lt;/P&gt;
&lt;P&gt;That's the only situation I know of in which emitting a no-op can cause a serious semantic change in a program -- turning a working program into a deadlocking one. And that sucks. &lt;/P&gt;
&lt;P&gt;I've been talking with some of the CLR jitter and threading guys about ways we can fix this more robustly than merely removing the no-op. I'm hoping we'll figure something out for some future version of the C# language.&lt;/P&gt;
&lt;P&gt;As for the bit about emitting null checks: indeed, at the time of a call to an instance method, whether virtual or not, we guarantee that the object of the call is not null by throwing an exception if it is. The way this is implemented in IL is a little odd. There are two instructions we can emit: &lt;SPAN class=code&gt;call&lt;/SPAN&gt;, and &lt;SPAN class=code&gt;callvirt&lt;/SPAN&gt;. &lt;SPAN class=code&gt;call&lt;/SPAN&gt; does NOT do a null check and does a non-virtual call. &lt;SPAN class=code&gt;callvirt&lt;/SPAN&gt; does do a null check and does a virtual call if it is a virtual method, or a non-virtual call if it is not.&lt;/P&gt;
&lt;P&gt;If you look at the IL generated for a non-virtual call on an instance method, you'll see that sometimes we generate a &lt;SPAN class=code&gt;call&lt;/SPAN&gt;, sometimes we generate a &lt;SPAN class=code&gt;callvirt&lt;/SPAN&gt;. Why? We generate the &lt;SPAN class=code&gt;callvirt&lt;/SPAN&gt; when we want to force the jitter to generate a null check. We generate a &lt;SPAN class=code&gt;call&lt;/SPAN&gt; when we know that no null check is necessary, thereby allowing the jitter to skip the null check and generate slightly faster and smaller code.&lt;/P&gt;
&lt;P&gt;When do we know that the null check can be skipped? If you have something like &lt;SPAN class=code&gt;(new Foo()).FooNonVirtualMethod()&lt;/SPAN&gt; we know that the allocator never returns null, so we can skip the check. It's a nice, straightforward optimization, but the realization in the IL is a bit subtle.&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4432044" 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/Code+Generation/default.aspx">Code Generation</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Threading/default.aspx">Threading</category></item><item><title>Why are base class calls from anonymous delegates nonverifiable?</title><link>http://blogs.msdn.com/ericlippert/archive/2005/11/14/why-are-base-class-calls-from-anonymous-delegates-nonverifiable.aspx</link><pubDate>Mon, 14 Nov 2005 22:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:492607</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/492607.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=492607</wfw:commentRss><description>&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;I'm still learning my way around the C# codebase – heck, I'm still learning my way around the Jscript codebase and I've been working on it for nine years, not nine weeks. Here's something I stumbled across while refactoring the anonymous method binding code last week that I thought might be interesting to you folks.&lt;/P&gt;
&lt;P&gt;Consider this simple program:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;using System;&lt;BR&gt;public delegate void D ();&lt;BR&gt;public class Alpha {&lt;BR&gt;&amp;nbsp; public virtual void Blah()&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Alpha.Blah");&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;public class Bravo : Alpha {&lt;BR&gt;&amp;nbsp; public override void Blah() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Bravo.Blah");&lt;BR&gt;&lt;FONT color=#ff0000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.Blah();&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;Pretty straightforward so far. Any &lt;STRONG&gt;virtual&lt;/STRONG&gt; call to &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Blah&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; on an instance of &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; does a &lt;STRONG&gt;non-virtual&lt;/STRONG&gt; call to the base class implementation. Now let's do a similar thing from an anonymous delegate in &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#000080 size=2&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;&amp;nbsp; public void Charlie()&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 123;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = delegate&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;When you compile this thing up you get a crazy-sounding warning:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;warning CS1911: Access to member 'Alpha.Blah()' through a 'base' keyword from an anonymous method or iterator results in unverifiable code. Consider moving the access into a helper method on the containing type.&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;And indeed, if you compile this up and run it through PEVERIFY.EXE, sure enough you'll get an unverifiable code warning. Unverifiable code requires full trust and is generally to be avoided – what is going on here?&lt;/P&gt;
&lt;P&gt;This is an artefact of the way that C# realizes anonymous delegates. The anonymous delegate above captures both &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; and &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;x&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;, and therefore we actually generate code that would look something like this if you decompiled it:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;public class Bravo : Alpha {&lt;BR&gt;&amp;nbsp; public override void Blah() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Bravo.Blah");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp; private class __locals {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int __x;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Bravo __this;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void __method() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.__this.blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#ff0000 size=2&gt;__nonvirtual__&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt; ((Alpha)this.__this).Blah());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(this.__x);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp; public void Charlie() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __locals locals = new __locals();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; locals.__x = 123;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; locals.__this = this;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = new D(locals.__method);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; d();&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;Of course there is no such thing in C# as &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;__nonvirtual__&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;, so really there is no way to decompile this thing back into real C#.&amp;nbsp; Which is exactly the problem! What's happening here is that we are doing a non-virtual call on a &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference which is not the "real" &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference of the call.&lt;/P&gt;
&lt;P&gt;That's a pretty suspicious programming practice.&amp;nbsp; People who build object hierarchies that manipulate sensitive information have a reasonable expectation that the &lt;I&gt;only&lt;/I&gt; way to call a base class implementation of a virtual method is from the derived class itself, not from some third-party method.&amp;nbsp; Therefore the CLR treats this as unverifiable code, and therefore we have to issue a warning. (I suppose the CLR team could have made an exception for nonvirtual references from classes scoped to within the class in question, or for that matter, classes from the same assembly, but they didn't.)&lt;/P&gt;
&lt;P&gt;Now, I was refactoring the code that generates the captured variable class, and so of course I wanted to write a few additional unit tests to make sure that I wasn't breaking anything. When I ran into this warning the first unit test that I wrote was actually a somewhat simplified version of the above:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;&amp;nbsp; public void Charlie()&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = delegate&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;This issues the warning above, but when I ran the generated executable through PEVERIFY I was surprised to discover that it verified just fine.&lt;/P&gt;
&lt;P&gt;As it turns out, the compiler is clever about this one. It sees that the only captured variable is the &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference, and therefore it can optimize away the locals class.&amp;nbsp; For this case it simply generates the anonymous method as just another method on the &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; class. Since this is a method of &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;, not a special locals class, the nonvirtual call is on the real &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference, so it is verifiable.&lt;/P&gt;
&lt;P&gt;We decided to issue the warning even in this case because we thought that it would make C# seem really weird and brittle to suddenly start issuing the warning when you add an additional outer local variable reference to the anonymous delegate. &lt;B&gt;Even when this doesn't actually generate nonverifiable code, it's a good idea to get in the habit of creating a helper method on the real class that does the nonvirtual access.&lt;/P&gt;&lt;/B&gt;
&lt;P&gt;Of course, all of the stuff above is implementation details. &lt;B&gt;You cannot rely upon future versions of C# to continue to generate anonymous methods in this manner.&lt;/B&gt; We probably will, but who knows what new features will be added to the CLR that might make it possible to not generate a bunch of hidden classes behind the scenes to do this work? Please do not attempt to do anything silly like reflecting upon the class to discover the hidden nested classes and use them; you're just asking for future pain if you do.&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=492607" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</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></item></channel></rss>