More Re: Function Argument Evaluation argument

Blair P. Houghton bhoughto at pima.intel.com
Fri Mar 29 16:13:49 AEST 1991


In article <17983 at crdgw1.crd.ge.com> volpe at camelback.crd.ge.com (Christopher R Volpe) writes:
>But the only reason you were able to produce an order of evaluation that
>resulted in "200 200" is because the program did something it should never
>have done in the first place, which was to modify p twice between sequence
>points.

He's got a definite point, here [1].  Neither of the
expressions in this list of function arguments is a
full-expression [2], and neither contains any of the
operators that define sequence points [3], so the
only sequence-point around is the one before the
function-call [4].  Thus, using p twice in an lvalue
context renders the behavior undefined [5].

[1] ANSI X3.159-1989, sec. 3.3, p. 39, ll. 5-7.
[2] Ibid., Appendix B, p. 189.
[3] Ibid.
[4] Ibid (dangit! no line numbers! <grouse>).
[5] See also p. 39, footnote 34.

Maybe this also answers John Gingerich's question (and if I
still didn't understand it then I really don't understand
it) about "is it undefined?"  I was wrong.  The arguments'
behavior is undefined, so the statement's is undefined, so the
program's is undefined, and the compiler can tune up its
pipes and start tooting "Daaaaaii-seeeee, Daaai-seee, give
me your an-swer true..." [6]

>I would be very interested in seeing a program whose behavior
>was *not* undefined, yet could arbitrarily produce either of two
>drastically different outputs depending solely on the unspecified
>order of evaluation.

Insert a sequence-point:

	char *x = "foo", *y = "bar";

	printf("\t%s %s\n", (p = x)?p:"(nil)", (p = y) );

Now the behavior is defined, since there's a sequence point
after the first assignment to p, but no way to tell
which of the p's is returned after either question mark.

It is certain, however, that the second argument
must return "bar", since the first assignment was
before the sequence point at the `?', and everything else
is after that sequence point and before the function-call
sequence point.

This will print either

	foo bar

or

	bar bar

Depending on the order in which the placing of the first
argument on the stack and the assignment of y to p are
performed.  It seems to me, though, that since I asked
for "p" and not "the result of p only due to the first
argument", then the value should have to wait for the
side-effects (the actual storage is a side-effect
of assignment (sec. 3.3.16, p. 54, ll. 14-16)) of
other argument-expressions before it is placed on the
stack.

I didn't need the obfuscation of the `?:', either.

	f(p,p=y);

faces a similar nonspecificity of the values of the arguments
at the sequence point.

There's no rule against changing a stack value multiple
times between sequence points, either, so the stack could
get the first p, then the compiler could say "oops, p changed
due to an assignment, better fix the first one" and the new
value could be put on the stack.  If a compiler does this,
I'd like to have it.  It probably gets the rest of the standard
right, too.  But I can't count on it, since the standard
moots this interpretation.

				--Blair
				  "[6]  I get it.  '2001: A Space Odyssey'
				   is all about the perils of nonconformance.
				   :-) :-)  Kubrick, what a visionary!"



More information about the Comp.std.c mailing list