[comp.lang.c] Order of evaluation of nested function arguments

gnu@hoptoad.uucp (John Gilmore) (02/02/88)

Richard Stallman and I have a disagreement over whether the ANSI
standard specifies an order of evaluation for this statement
(taken from an implementation of Ackermann's function):

	return(A(--x,A(x,--y)));

In the oct 86 draft standard, it says that (3.3) "the evaluation of the
operands of an operator that involves a sequence point shall not be
interleaved with other evaluations".  The function call operator
clearly involves a sequence point (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".

This means to me that A(x,--y) must be evaluated before the --x,
because the evaluation of A, x, and --y for the inner function call
cannot be interleaved with the evaluation of A, --x, and A(x,--y) for
the outer one.

This is probably an unintended consequence of the "no interleaving"
rule, which as I recall was written for cases involving ?: in getc().
For all I know, the wording has been modified in future draft standards
which are as yet unavailable to the public.

Richard claims the order of evaluation here is undefined.  Anybody
know?  Anybody care?  Here's the test program (gnu12.c), which gcc-1.17
"fails" if I am correct.

	John

/* Ackerman's function */
main()
{
	int i;

	i = A(3,6);
	if (i == 509)
		printf("Test passed\n");
	else
		printf("FAILED ackerman's(3, 6): %d\n", i);
}

A(x,y)
int x,y;
{
    if(x==0) return(++y);
    if(y==0) return(A(--x,1));
    return(A(--x,A(x,--y)));
    }
-- 
{pyramid,ptsfa,amdahl,sun,ihnp4}!hoptoad!gnu			  gnu@toad.com
		"Watch me change my world..." -- Liquid Theatre

franka@mmintl.UUCP (Frank Adams) (02/03/88)

In article <3995@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>	return(A(--x,A(x,--y)));
>
>In the oct 86 draft standard, it says that (3.3) "the evaluation of the
>operands of an operator that involves a sequence point shall not be
>interleaved with other evaluations".  The function call operator
>clearly involves a sequence point (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".

I interpret this to mean that, from the point where the code starts
evaluating A(x,--y), until the actual call, nothing else can be executed.
But it does not mean that A(x,--y) must be evaluated before the --x is.  On
such an interpretation, there would be no legal evaluation order at all for,
e.g., A(A(--x,y),A(x,--y)).

The call A(x,--y) is not being "interleaved" with the evaluation of the
outer A and --x, because it is *part of* that evaluation.
-- 

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Ashton-Tate          52 Oakland Ave North         E. Hartford, CT 06108

jss@hector.UUCP (Jerry Schwarz) (02/04/88)

In article <3995@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>Richard Stallman and I have a disagreement over whether the ANSI
>standard specifies an order of evaluation for this statement
>(taken from an implementation of Ackermann's function):
>
>	return(A(--x,A(x,--y)));
>
>In the oct 86 draft standard, it says that (3.3) "the evaluation of the
>operands of an operator that involves a sequence point shall not be
>interleaved with other evaluations".  The function call operator
>clearly involves a sequence point (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".
>
>This means to me that A(x,--y) must be evaluated before the --x,
>because the evaluation of A, x, and --y for the inner function call
>cannot be interleaved with the evaluation of A, --x, and A(x,--y) for
>the outer one.
>

Your interpretation is not consistent.  It would mean that there was
no way to evaluate F(F(x),F(y)), because you would require F(x) to be
evaluated before F(y) and visa versa.

What the draft standard is saying is that the evaluations A, x, --y
and the function call must occur as a unit.  For example it is
prohibiting  the order  "A, x, --x, --y, call".  The orders
"--x,A,x,--y,call" and "A,x,--y,call,--x" are both allowed since the
relevant evaluations are not "interleaved" with other evaluations
but are performed either before or after.

I'm pretty sure that the example of concern to the committee was
something like

	((a=5),a) + ((a=6),a)

PCC derived compilers tend to evaluate this in the order "a=5",
"a=6", "a", "a", "do the sum".   The words quoted above from the
draft standard would disallow that order.

Jerry Schwarz

pardo@june.cs.washington.edu (David Keppel) (02/04/88)

[ a sequence point shall not be interleaved with other operations ]

Just out of curiosity, why?  (Like what kinds of crazy problems do you
get when you try to stuff seq. pts. into the middle of expressions)

	;-D on  ("You know you're in trouble")  Pardo