* remove "\r" nonsense
[mascara-docs.git] / C / the.ansi.c.programming.language / notes.accompany.ansi.c / sx5l.html
blob782490f8a9fa56d0b1bc47723b578970503b32a9
1 <!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995, 1996 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
5 <html>
6 <head>
7 <link rev="owner" href="mailto:scs@eskimo.com">
8 <link rev="made" href="mailto:scs@eskimo.com">
9 <title>section 2.12: Precedence and Order of Evaluation</title>
10 <link href="sx5k.html" rev=precedes>
11 <link href="sx6.html" rel=precedes>
12 <link href="sx5.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>section 2.12: Precedence and Order of Evaluation</H2>
17 <p>Note that precedence is <em>not</em> the same thing as order of evaluation.
18 Precedence determines how an expression is parsed,
19 and it has an influence on the order in which parts of it are
20 evaluated,
21 but the influence isn't as strong as you'd think.
22 Precedence says that in the expression
23 <pre> 1 + 2 * 3
24 </pre>the multiplication happens
25 before the addition.
26 But if we have several function calls,
27 such as
28 <pre> f() + g() * h()
29 </pre>we have no idea which function will be called first;
30 the compiler might arrange to call <TT>f()</TT> first even
31 though its value won't be needed until last.
32 If we were to write an abomination like
33 <pre> i = 1;
34 a[i++] + a[i++] * a[i++]
35 </pre>we would have <em>no</em> way of knowing which order the three
36 increments would happen in,
37 and in fact the compiler wouldn't have any idea either.
38 We could <em>not</em> argue that since multiplication has
39 higher precedence than addition, and since multiplication
40 associates from left to right, the second <TT>i++</TT> would have to
41 happen first, then the third, then the first.
42 (Actually, associativity <em>never</em> says anything about
43 which side of a single binary operator gets evaluated first;
44 associativity says which of several adjacent same-precedence
45 operators happens first.)
46 </p><p>In general,
47 you should be wary of ever trying to
48 second-guess the relative order
49 in which the various parts of an expression will be evaluated,
50 with two exceptions:
51 <OL><li>You can obviously assume that precedence will dictate
52 the order in
53 which binary operators
54 are applied.
55 This typically says more than just what order things happens in,
56 but also what the expression actually <em>means</em>.
57 (In other words,
58 the precedence of <TT>*</TT> over <TT>+</TT>
59 says more than that the multiplication ``happens first''
60 in <TT>1 + 2 * 3</TT>;
61 it says that the answer is 7, not 9.)
62 <li>You can assume that the <TT>&amp;&amp;</TT> and <TT>||</TT> operators
63 are evaluated left-to-right,
64 and that the right-hand side is not evaluated at all
65 if the left-hand side determines the outcome.
66 </OL></p><p>To look at one more example,
67 it might seem that the code
68 <pre> int i = 7;
69 printf("%d\n", i++ * i++);
70 </pre>would have to print 56, because no matter which order the
71 increments happen in, 7x8 is 8x7 is 56.
72 But <TT>++</TT> just says that the increment happens later,
73 not that it happens immediately,
74 so this code could print 49
75 (if it chose to perform the multiplication first,
76 and both increments later).
77 And,
78 it turns out that ambiguous expressions like this are such a
79 bad idea that the ANSI C Standard does not require compilers to
80 do anything reasonable with them at all,
81 such that
82 the above code
83 might end up
84 printing 42, or 8923409342, or 0, or crashing
85 your computer.
86 </p><p>Finally,
87 note that parentheses don't dictate overall evaluation
88 order any more than precedence does.
89 Parentheses override precedence
90 and say which operands go with which operators,
91 and they therefore affect the overall meaning of an expression,
92 but they don't
93 say anything about the order of subexpressions or side effects.
94 We could not ``fix''
95 the evaluation order of
96 any of the
97 expressions we've been discussing
98 by adding parentheses.
99 If we wrote
100 <pre> f() + (g() * h())
101 </pre>we still wouldn't know whether
102 <TT>f()</TT>, <TT>g()</TT>, or <TT>h()</TT>
103 would be called first.
104 (The parentheses would force the multiplication to happen before the addition,
105 but precedence already would have forced that, anyway.)
106 If we wrote
107 <pre> (i++) * (i++)
108 </pre>the parentheses wouldn't force the increments to happen before
109 the multiplication or in any well-defined order;
110 this parenthesized version would be just as undefined as
111 <TT>i++ * i++</TT> was.
112 </p><p>page 53
113 </p><p>Deep sentence:
114 <blockquote>Function calls,
115 nested assignment statements,
116 and increment and decrement operators cause
117 ``side effects''--some
118 variable is changed as a by-product of the evaluation of an expression.
119 </blockquote>(There's a slight inaccuracy in this sentence:
120 <em>any</em> assignment expression counts as a side effect.)
121 </p><p>It's these ``side effects'' that you want to keep in
122 mind when you're making sure that your programs are well-defined
123 and don't suffer any of the undefined behavior we've been
124 discussing.
125 (When we informally said that
126 complex expressions had several things going on ``at once,''
127 we were actually referring to expressions with multiple side effects.)
128 As a general rule,
129 you should make sure that each expression only has one side effect,
130 or if it has several,
131 that <em>different</em> variables are changed by the several side effects.
132 </p><p>page 54
133 </p><p>Deep sentence:
134 <blockquote>The moral is that writing code
135 that depends on order of evaluation
136 is a bad programming practice in any language.
137 Naturally,
138 it is necessary to know what things to avoid,
139 but if you don't know
140 <I>how</I>
141 they are done on various machines,
142 you won't be tempted to take advantage of a particular implementation.
143 </blockquote></p><p>The first edition of K&amp;R said
144 <blockquote>...if you don't know
145 <I>how</I>
146 they are done on various machines,
147 that innocence may help to protect you.
148 </blockquote>I actually prefer the first edition wording.
149 Many textbooks encourage you to write small programs
150 to find out how your compiler
151 implements some of these ambiguous expressions,
152 but it's
153 just
154 one step from writing a small program to find out,
155 to writing a real program which makes use of what you've just learned.
157 you <em>don't</em> want to write programs
158 that work only under one particular compiler,
159 that take advantage of the way that compiler
160 (but perhaps no other)
161 happens to implement the undefined expressions.
162 It's fine to be curious about what goes on ``under the hood,''
163 and many of you will be curious enough about what's going on
164 with these ``forbidden'' expressions that you'll want to
165 investigate them,
166 but please keep very firmly in mind that,
167 for real programs,
168 the very easiest way of dealing with ambiguous, undefined expressions
169 (which one compiler interprets one way
170 and another interprets another way
171 and a third crashes on)
172 is not to write them in the first place.
173 </p><hr>
175 Read sequentially:
176 <a href="sx5k.html" rev=precedes>prev</a>
177 <a href="sx6.html" rel=precedes>next</a>
178 <a href="sx5.html" rev=subdocument>up</a>
179 <a href="top.html">top</a>
180 </p>
182 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
183 // <a href="copyright.html">Copyright</a> 1995, 1996
184 // <a href="mailto:scs@eskimo.com">mail feedback</a>
185 </p>
186 </body>
187 </html>