On Friday 25 February 2011 22:32:47 Ali Çehreli wrote: > On 02/25/2011 06:10 PM, Jonathan M Davis wrote: > > On Friday, February 25, 2011 17:31:36 Ali Çehreli wrote: > >> On 02/25/2011 05:09 PM, bearophile wrote: > >> > int j; > >> > int[2] y; > >> > y[j] = j = 1; > >> > >> I think that's undefined behavior in C and C++. It is not defined > >> whether j's previous or past value is used in y[j]. > >> > >> I would expect the situation be the same in D. > > > > No, that should be perfectly defined. What's undefined is when you do > > something like func(j, y[j]). The evaluation order of the function > > arguments is undefined. However, the evaluation order when dealing with > > an assignment should be defined. I _could_ be wrong about that, but > > there's no question that the assignments themselves are guaranteed to be > > done in right-to-left order. > > > > - Jonathan M Davis > > Standard texts are very difficult to read. I found a 2005 draft of the > C++ standard. 5 Expressions, paragraph 4: > > <quote> > Except where noted, the order of evaluation of operands of individual > operators and subexpressions of individual expres- > sions, and the order in which side effects take place, is > unspecified.58) Between the previous and next sequence point a > scalar object shall have its stored value modified at most once by the > evaluation of an expression. Furthermore, the prior > value shall be accessed only to determine the value to be stored. The > requirements of this paragraph shall be met for > each allowable ordering of the subexpressions of a full expression; > otherwise the behavior is undefined. [ Example: > i = v [ i ++]; / / the behavior is undefined > i = 7 , i ++ , i ++; / / i becomes 9 > i = ++ i + 1; / / the behavior is undefined > i = i + 1; / / the value of i is incremented > — end example ] > </quote> > > To complete, footnote 58 is: > > <quote> > 58) > The precedence of operators is not directly specified, but it can be > derived from the syntax. > </quote> > > The section for the assignment operator does not mention anything to the > contrary. According to my current understanding and my now-hazy > recollections of old discussions on C++ news groups, in the following > statement > > a() = b() = c(); > > the value of c() is assigned to b(), and the value of that expression is > assigned to a(); but the order in which the three expressions are > evaluated are unspecified. > > Hence, if the code behaves contrary to 5.1 above, it has undefined > behavior. > > This was bearophile's statement: > > y[j] = j = 1; > > The assignment operators do not introduce sequence points; there are > only two: before and after the whole line above. The code does not obey > "the prior value shall be accessed only to determine the value to be > stored". Above, the prior value is used to determine which element of y > is being assigned to.
Bleh. Well, good to know. Walter wants to make the order such evaluations ordered in D at some point though, so eventually it won't be a problem in D - though it'll obviously still be a problem in C++. Regardless, avoiding to alter a variable and use it multiple times within the same statement or expression is a good idea. - Jonathan M davis