Neil Conway wrote: > The text is the same in both versions: > > http://dev.unicals.com/papers/c89-draft.html#3.3.2.2 > > "The order of evaluation of the function designator, the arguments, and > subexpressions within the arguments is unspecified, but there is a > sequence point before the actual call." > > (On reading this more closely, I suppose you could make the argument > that a function call that takes place in the argument list of another > function call is a "subexpression within the [outer function's] > arguments", so the order of evaluation prior to the call of the outer > function would be undefined. But I don't think that's the right reading > of the standard.)
That is pretty much what I remember hearing at the time. To me what this says is only that (the program will behave as if) all arguments shall be evaluated before the function is called--but in an otherwise unspecified order. What we're currently doing has this basic shape: int x = 0; static int a() { x = 1; return x; } static int b() { printf("b sees x=%d\n", x); return x;} static int c(int l, int r) { printf("c sees x=%d\n", x); return x; } int main() { return c(a(),b()); } Now, the best we can hope for based on what you quote is that we will see "c sees x=1" but we don't know what we'll see coming out of b(). And the wording makes it equally clear that we would not change any of this by doing c(b(),a()) instead of c(a(),b()). The "best we can hope for" depends on the definition of "unspecified." This is where it gets really tricky. I see two different possible implications depending on that definition: (optimistic) The program will execute as if the code said either "t1=a(); t2=b(); c(t1,t2)" or "t1=b(); t2=a(); c(t1,t2)" but we don't know which. I wouldn't bet on this one as a guarantee, although naive compilers will probably behave like this. (pessimistic) The executions of a() and b() may be interspersed freely, although as a practical matter the compiler will respect the sequence points within each. But that still means there is no sequence point between any one given expression in the execution of a() and any other in the execution of b(), therefore setting a variable in a() and also touching it in b() leaves behaviour undefined. The program may react in any way it likes without violating the standard, including traveling back in time and refusing to start at all (really!), going off to make tea, or standing on its head and donning a tutu. A well-known way to trigger undefined behaviour is "x++=x++;" because there is no sequence point between the two side effects. Try it: gcc will give you a stern warning. Given that there is no sequence point between argument expressions, as per the paragraph you quote, the same must go for "c(x++,x++)". So then it becomes dubious that there is suddenly a guarantee for "c(a(),b())"! Jeroen ---------------------------(end of broadcast)--------------------------- TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]