TITLE: Sequence points and order-of-evaluation PROBLEM: ian@cs.mcgill.ca (Ian Frederic STEWART) cout << "i1:" << i << " ++i:" << ++i << " i2:" << i << endl; RESPONSE: Steve Clamage (clamage@Eng.Sun.COM) This program modifies variable 'i' twice with no intervening sequence point, which results in undefined behavior. It also references 'i' other than to determine its value for purposes of modification, which also results in undefined behavior. Any result at all, including a core dump, is allowed by the language definition. RESPONSE: alik@gauss.Stanford.EDU (Alik) I am not sure I understand that... As far as I can see (I have rather limited compiler design experience), this is just a metter of operator precedence. RESPONSE: clamage@Eng.Sun.COM (Steve Clamage), 10 Jan 95 Precedence and order of evaluation are not the same thing. Precedence specifies grouping of operations. Among most operators with the same precedence, for example, the order of evaluation is not specified. Simple example: a*b + c*d The precedence of multiplication is higher than addition, so that a*b and c*d must be evaluated before the results are added. But it is unspecified whether a*b or c*d is evaluated first. If any of 'a', 'b', 'c', or 'd' had side effects (that is, they are themselves more complicated expressions), you cannot know which will occur first. If the value of 'a' could depend on whether 'd' was evaluated first, you cannot predict the value of the expression. C and C++ define "sequence points", which are points such that all side effects to the left of the sequence point must have all occurred before anything to the right of the sequence point is evaluated. For example, there is a sequence point at a semicolon, meaning that portions of different statements cannot in general be interleaved. Let's consider a simplified version of the original expression: cout << ++i << ++i; This is equivalent to op<<( op<<(cout, ++i), ++i); There is a sequence point after evaluation of all function parameters and before the function call, so the inner ++i must be evaluated before the inner call to op<<. But there is no sequence point between parameters to a function, so the inner call to op<< may occur before or after the evaluation of the outer ++i. Further, the value of ++i for the outer call might be evaluated but the new value not stored back in 'i' until after the call to the inner op<<. (The storing back is the side effect, which does not have to be completed before the call to the outer op<<). This leaves several reasonable sequences of code generation. The expression could in particular print "11", "12", "21", or "22". In fact, rather than try to codify the permissible results from multiple modifications of the same object, the language definition places no requirements on the program at all.