<?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 : precedence</title><link>http://blogs.msdn.com/ericlippert/archive/tags/precedence/default.aspx</link><description>Tags: precedence</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><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>Precedence vs Associativity vs Order</title><link>http://blogs.msdn.com/ericlippert/archive/2008/05/23/precedence-vs-associativity-vs-order.aspx</link><pubDate>Fri, 23 May 2008 17:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8523592</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>13</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8523592.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8523592</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/oldnewthing/archive/2007/08/14/4374222.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2007/08/14/4374222.aspx"&gt;Raymond has written about this&lt;/A&gt;, I&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx"&gt; have written about Raymond writing about it&lt;/A&gt;, but I still frequently get questions from people who are unclear on the difference between precedence, associativity and evaluation order.&lt;/P&gt;
&lt;P&gt;I suspect that this confusion arises from the difference between how most people are trained to&amp;nbsp;evaluate arithmetical expressions versus how compilers generate code to evaluate arithmetical expressions. As a child it was drilled into me that the way to evaluate an arithmetical expression was to recursively apply the PEDMAS rule. That is, evaluate anything in parentheses first. Then evaluate any exponentiations. Then divisions, multiplications, additions and subtractions, in that order. So if you had 4 x 5 x (20 - 12 / 3) you start by evaluating what's in parentheses: 20 - 12 / 3. In there, there are no parens or exponents, so start with the division. Replace 12 / 3 with 4 to get 20 - 4. Then evaluate the subtraction to get 16. Now we have the value for the parens, and we are down to 4 x 5 x 16. Evaluate one of the multiplications -- but wait, we do not know what order to evaluate the multiplications in. But we can do it in any old order, so lets say 5 x 16 is 80, so we have 4 x 80, which is 320, done.&lt;/P&gt;
&lt;P&gt;You'll notice that the algorithm that I was taught emphasizes that you do the work on whatever is in the deepest set of parentheses first, no matter what. Many people believe that arithmetical expressions in programming languages work the same way. &lt;STRONG&gt;They do not.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Rather, in programming languages, parentheses indicate how the results of evaluations are combined, but not necessarily the order in which the calculations are carried out. In languages with no side effects, the order of evaluation is irrelevant. But in languages where side effects might occur, order becomes relevant.&lt;/P&gt;
&lt;P&gt;The evaluation of an arithmetical expression is controlled by three sets of rules: precedence rules, associativity rules, and order rules.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Precedence&lt;/STRONG&gt; rules describe how an underparenthesized expression should be parenthesized &lt;EM&gt;when the expression mixes different kinds of operators&lt;/EM&gt;. For example, multiplication is of higher precedence than addition, so 2 + 3 x 4 is equivalent to 2 + (3 x 4), not (2 + 3) x 4.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Associativity&lt;/STRONG&gt; rules describe how an underparenthesized expression should be parenthesized when the expression has a bunch of the same kind of operator. For example, addition is associative from left to right, so a + b + c is equivalent to (a + b) + c, not a + (b + c). In ordinary arithmetic, these two expressions always give the same result; in computer arithmetic, they do not necessarily. (As an exercise can you find values for a, b, c such that (a + b) + c is unequal to a + (b + c) in C#?)&lt;/P&gt;
&lt;P&gt;Now the confusing one.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Order of evaluation&lt;/STRONG&gt; rules describe the order in which each operand in an expression is evaluated. The parentheses just describe how the results are grouped together; "do the parentheses first" is not a rule of C#. Rather, the rule in C# is "evaluate each subexpression strictly left to right". &lt;/P&gt;
&lt;P&gt;The expression &lt;SPAN class=code&gt;F() + G() * H()&lt;/SPAN&gt; is equivalent to &lt;SPAN class=code&gt;F() + (G() * H())&lt;/SPAN&gt;, but C# does NOT evaluate &lt;SPAN class=code&gt;G() * H()&lt;/SPAN&gt; before &lt;SPAN class=code&gt;F().&lt;/SPAN&gt; Rather, this is equivalent to:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;temp1 = F();&lt;BR&gt;temp2 = G();&lt;BR&gt;temp3 = H();&lt;BR&gt;temp4 = temp2 * temp3;&lt;BR&gt;result&amp;nbsp;= temp1 + temp4;&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Another way to look at it is that the rule in C# is not "do the parentheses first", but rather to parenthesize everything then recursively apply the rule "evaluate the left side, then evaluate the right side, then perform the operation".&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;This is not a rule of C++.&lt;/STRONG&gt; In C++, F(), G() and H() can be evaluated in whatever order the compiler chooses, so long as it combines the results in the right way. A legal C++ compiler might do left to right, right to left, parentheses first, whatever the compiler writer felt like. &lt;/P&gt;
&lt;P&gt;The way this topic usually comes up is when someone has an expression chock full of side effects -- assignments, increments, decrements, pointer stores and so on, which they are attempting to convert from C++ to C#, and report the "bug" in the C# compiler to me that C# does not follow the "rules" of C++. Which is ironic, because since there are not actually any &lt;EM&gt;rules&lt;/EM&gt; in C++ about order of evaluation between two sequence points. Thus the &lt;EM&gt;bug&lt;/EM&gt; actually is that their code was never portable C++, and only worked because the code author happened to know (or guess) what ordering the compiler writer chose.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8523592" 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/precedence/default.aspx">precedence</category></item><item><title>C++ and the Pit Of Despair</title><link>http://blogs.msdn.com/ericlippert/archive/2007/08/14/c-and-the-pit-of-despair.aspx</link><pubDate>Tue, 14 Aug 2007 18:25:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4385879</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/4385879.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=4385879</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.msdn.com/oldnewthing/archive/2007/08/14/4374222.aspx" mce_href="http://blogs.msdn.com/oldnewthing/archive/2007/08/14/4374222.aspx"&gt;Raymond has an interesting post today&lt;/A&gt; about two subtle aspects of C#: how order of&amp;nbsp;evaluation in an expression&amp;nbsp;is specified as strictly left-to-right, and how the rules&amp;nbsp;regarding local shadowing ensure that an identifier has exactly one meaning in a local scope. He makes an educated guess that the reason for these sorts of rules is to "&lt;EM&gt;reduce the frequency of a category of subtle bugs&lt;/EM&gt;".&lt;/P&gt;
&lt;P&gt;I'd like to take this opportunity to both confirm that guess and to expand upon it a bit.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eliminating Subtle Bugs&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You remember in &lt;EM&gt;The Princess Bride&lt;/EM&gt; when Westley wakes up and finds himself&amp;nbsp;locked in&amp;nbsp;&lt;A class="" href="http://www.wavcentral.com/movies/pbride.html" mce_href="http://www.wavcentral.com/movies/pbride.html"&gt;The Pit Of Despair&lt;/A&gt;&amp;nbsp;with a hoarse&amp;nbsp;albino and the sinister six-fingered man, Count Rugen?&amp;nbsp;The principle&amp;nbsp;idea of a pit of despair is twofold.&amp;nbsp;First, that it is a &lt;EM&gt;pit&lt;/EM&gt;, and therefore easy to fall into but&amp;nbsp;difficult work to climb out of. And second, that it induces &lt;EM&gt;despair&lt;/EM&gt;. Hence the name.&lt;/P&gt;
&lt;P&gt;I often think of C++ as my own personal Pit of Despair Programming Language.&amp;nbsp;Unmanaged C++ makes it so easy to fall into traps. Think buffer overruns, memory leaks, double frees, mismatch between allocator and deallocator, using freed memory, umpteen dozen ways to trash the stack or heap -- and those are just some of the memory issues. There are lots more "gotchas" in C++. C++ often throws you into the Pit of Despair and you have to climb your way up the Hill of Quality. (Not to be confused with scaling the Cliffs of Insanity. That's different.)&lt;/P&gt;
&lt;P&gt;Now, &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2007/05/14/why-are-overloaded-operators-always-static-in-c.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2007/05/14/why-are-overloaded-operators-always-static-in-c.aspx"&gt;as I've said before, the design of C# is not a subtractive process&lt;/A&gt;.&amp;nbsp;It is not "C++ with the stupid parts taken out". But that said, it would be rather foolish of us to not look at what problems people have typically had with&amp;nbsp;other languages and work to ensure that those exact same problems do not crop up&amp;nbsp;for C# users. I would like C# to be a "Pit of Quality" language, &lt;EM&gt;a language where its rules encourage you to write correct code in the first place&lt;/EM&gt;. You have to work quite hard to write a buffer overrun bug into a&amp;nbsp;C# program, and that's on purpose. &lt;/P&gt;
&lt;P&gt;I have never written a buffer overrun in C#. I have never written a bug where I accidentally shadowed a variable in another scope in C#. I have never used stack memory after the function returned in C#. I've done all those things in C++ multiple times, and it's not because I'm an idiot, it's because C++ makes it easy to do all those things accidentally and C# makes it very hard. Making it easy to do good stuff is obviously goodness; &lt;EM&gt;thinking about how to make it hard to do bad is actually more important.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;Now, given that the design of C# is not subtractive, we have to consider the pros and cons of each decision. Is there any compelling user &lt;EM&gt;benefit&lt;/EM&gt; in a &lt;EM&gt;deliberate&lt;/EM&gt;&amp;nbsp;&lt;EM&gt;failure&lt;/EM&gt; to specify what order functions in an expression are evaluated?&amp;nbsp;The only benefit I can think of is "not breaking some existing users of two existing incompatible implementations by declaring one of the implementations to be wrong", which is the situation that the C&amp;nbsp;standardization committee frequently found itself in, I'm sure. When C# was a new language that wasn't an issue, so we were free to pin that down early. Doing so has compelling benefits; it prevents subtle bugs, and as I'll discuss in a moment, there are other benefits as well.&lt;/P&gt;
&lt;P&gt;So, long story short, yes, designing the language so as to&amp;nbsp;prevent certain categories of subtle bugs is a huge priority for us.&amp;nbsp;However, there are other reasons too. For instance:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Uncertainty sometimes has high value but only in special contexts&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Like Vroomfondel said, "&lt;EM&gt;we demand rigidly defined areas of doubt and uncertainty!&lt;/EM&gt;" Ideally, those areas should be small and should afford some way for users to eliminate the uncertainty. Nondeterministic finalization is a good example. We deliberately do not specify when and in what order finalizers run because: &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;the vast majority of the time it makes no difference,&lt;/LI&gt;
&lt;LI&gt;relying on a particular timing or ordering of finalization some small percentage of the time is probably a subtle bug waiting to happen,&lt;/LI&gt;
&lt;LI&gt;specifying it would require us to simplify the implementation to the point where it actually could be specified, thereby destroying much of its value; there is value in that complexity&lt;/LI&gt;
&lt;LI&gt;specifying it ties our hands to make algorithm improvements in the future&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;But we do provide a mechanism (the "using" statement) whereby if you do need to ensure that a finalizer runs at a particular point, there is an easy syntax for it.&lt;/P&gt;
&lt;P&gt;With the possible exception of point 2, the order of evaluation of sub-expressions does not have these problems. It often does make a difference, the implementation is already simple enough that the specification is trivial, and its&amp;nbsp;unlikely that we are going to come up with some incredible improvement in the algorithm which determines what order subexpressions are evaluated in. And if by some miracle we do, the specification does take care to call out that if we can prove that out-of-order evaluation cannot introduce subtle bugs, then we reserve the right to do it.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Uncertainty is hard on the language implementation team&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;When I am implementing part of the language specification, of course I want great freedom to decide &lt;EM&gt;how to implement&lt;/EM&gt; a particular chunk of semantics. The language specification is not in the business of telling me whether we should be using a hand-written recursive descent parser or a parser-generator that consumes the grammar, etc. But I hate, hate, &lt;EM&gt;hate&lt;/EM&gt; when I'm reading the specification and I'm left with a choice of &lt;EM&gt;what semantics to implement&lt;/EM&gt;. I &lt;EM&gt;will&lt;/EM&gt; choose wrong. I know this, because &lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2006/06/27/648681.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2006/06/27/648681.aspx"&gt;when I ask you guys what the "intuitively obvious" thing to do is, significant fractions of the population disagree&lt;/A&gt;! &lt;/P&gt;
&lt;P&gt;Uncertainty is also hard on our testers -- they would like to know whether the language is correct, and being told "the specification is unclear, therefore whatever we do is correct" makes their jobs harder because that's a lie. Crashing horribly is probably not correct. Deadlocking is probably not correct. Somewhere on that spectrum between clearly correct behaviour and clearly incorrect behaviour is a line, and one of testing's jobs is to ensure that the developers produced an implementation that falls on the "correct" side of that line. Not knowing precisely where the line is creates unnecessary work for them, and they are overworked already.&lt;/P&gt;
&lt;P&gt;And uncertainty is hard on our user education people. They want to be able to write documentation which clearly describes what semantics the implementation actually implements, and they want to be able to write sample programs to illustrate it.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Uncertainty&amp;nbsp;erodes confidence&lt;/STRONG&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And finally, uncertainty erodes confidence in our users that we have a quality product that was designed with deep thought, implemented with care, and behaves predictably and sensibly. People entrust the operation of multi-million dollar businesses to their C# code; they're not going to do that if we can't even reliably tell them what "(++i) + i +&amp;nbsp;(i++)" does!&lt;/P&gt;
&lt;P&gt;*****&lt;/P&gt;
&lt;P&gt;Next time on FAIC I think I'll talk a bit about a related principle of language design: how we think about issues involving "breaking changes". I'll be expanding upon &lt;A class="" href="http://blogs.msdn.com/nealho/archive/2005/11/22/496101.aspx" mce_href="http://blogs.msdn.com/nealho/archive/2005/11/22/496101.aspx"&gt;an excellent article written a couple of years ago by my colleague Neal&lt;/A&gt;, so you might want to start there.&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=4385879" 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/Best+Of+FAIC/default.aspx">Best Of FAIC</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/precedence/default.aspx">precedence</category></item><item><title>Bad Recursion Revisited</title><link>http://blogs.msdn.com/ericlippert/archive/2005/04/28/bad-recursion-revisited.aspx</link><pubDate>Thu, 28 Apr 2005 21:12:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:413061</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>22</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/413061.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=413061</wfw:commentRss><description>&lt;FONT face="lucida sans unicode"&gt;&lt;FONT color=#800080 size=2&gt;
&lt;P&gt;We have internal email lists for questions about programming languages. Here's one that came across recently that I thought illustrated a good point about language design. &lt;/P&gt;
&lt;P&gt;An interview candidate gave the following awful implementation of the factorial function. (Recall that factorial is notated "n!", and is defined as the product of all the integers from 1 to n. 0! is defined as 1. So 4! = 4 x 3 x 2 x 1 = 24.)&lt;/P&gt;
&lt;P&gt;If you note that n! = n x ((n-1)!) then a &lt;/FONT&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/05/19/135392.aspx"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;recursive solution&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#800080 size=2&gt; comes to mind. When asked to implement the factorial function in C, an interview candidate came up with this:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#333399 size=2&gt;
&lt;P&gt;int F(int x){&lt;BR&gt;&amp;nbsp; return (x &amp;gt; 1) ? (x * F(--x)) : x;&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#800080 size=2&gt;
&lt;P&gt;Now, leaving aside for the moment the fact that &lt;/FONT&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/5/20.aspx"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;this&amp;nbsp;badly-named function&amp;nbsp;does no bounds checking on the inputs, potentially consumes the entire stack, returns a wrong or nonsensical answer for inputs less than one, and is a recursive solution to a problem that can easily be solved with a simple lookup table&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#800080 size=2&gt;, it has another big problem -- it doesn't even return the correct answer for any input greater than one either! F(4) will return 6, not 24, in Microsoft C. &lt;/P&gt;
&lt;P&gt;And yet the &lt;I&gt;seemingly&lt;/I&gt; equivalent C#, JScript and VBScript programs return 24.&lt;/P&gt;
&lt;P&gt;The question was "What the heck is up with that?" &lt;/P&gt;
&lt;P&gt;This looks perfectly straightforward. If x is 4, then we evaluate the consequence of the trinary operator. 4 * F(3) = 4 * 3 * F(2) = 4 * 3 * 2 * F(1) = 4 * 3 * 2 * 1 = 24, right? What is broken with C?&lt;/P&gt;
&lt;P&gt;Page 52 of K&amp;amp;R has the answer.&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;"C, like most languages, does not specify the order in which the operands of an operator are evaluated. (The exceptions are &amp;amp;&amp;amp;, ||, ?: and ','.) For example, in a statement like x = f()+g(); f may be evaluated before g or vice versa; thus if either f or g alters a variable on which the other depends, x can depend on the order of evaluation."&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#800080 size=2&gt;
&lt;P&gt;The Microsoft C compiler actually evaluates the function call first, which causes x to be decremented &lt;I&gt;before&lt;/I&gt; the multiplication. So this is actually the same as 3 * F(3) = 3 * 2 * F(1) = 3 * 2 * 1 = 6.&lt;/P&gt;
&lt;P&gt;Why does the specification call out that the compiler can choose any order for subexpression evaluation? Because then the compiler can choose to optimize the order so that it consumes a small number of stack or register slots for the results. &lt;/P&gt;
&lt;P&gt;Of course, C&amp;nbsp;was written back in the dark ages --&amp;nbsp;the 1970's&amp;nbsp;-- when indeed most languages were pretty ill-specified and full of terrible "gotchas" like this. JScript, VBScript, C#, and most modern languages do guarantee that functions will be evaluated in left-to-right order. In all these languages, &lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000080&gt;x = f() + g() * h();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;will evaluate f, then g, then h.&lt;/P&gt;
&lt;P&gt;As K&amp;amp;R notes &lt;FONT color=#000000&gt;"The moral is that writing code that depends on order of evaluations is a bad programming practice in any language."&lt;/FONT&gt;&amp;nbsp; Amen to that!&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=413061" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/JScript/default.aspx">JScript</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/VBScript/default.aspx">VBScript</category><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/Code+Quality/default.aspx">Code Quality</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Recursion/default.aspx">Recursion</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/precedence/default.aspx">precedence</category></item></channel></rss>