[net.lang.c] Indirect comma assigned from side effects

rokicki@navajo.STANFORD.EDU (Tomas Rokicki) (08/19/86)

[ `---\-   For the plane eater ]

The question is whether the comma operator (which K&C guarantees will
evaluate its left operand before its right operand) may allow parts of
other expressions in the same statement to be evaluated somewhere in
the middle of the comma operands evaluation.

For example, consider the program:

	int lhs, rhs, index; int *pointers[9];
	foo() { *( index=lhs, pointers[index] ) = sideeffects(); }

The question is, does C allow for the possibility that the order
of evaluation might be "index=lhs" then "sideeffects()" then
"*pointers[index]=<result>"?  If so, then if "sideeffects()"
changes the value of "index", then the result of the statement
is not defined.  On the other hand, if C does not allow the
compiler to generate such code, then the statement is well
defined.

I realize that in general, K&C say that the order of expression
evaluation is not defined, but in certain circumstances it is,
and their wording does not make it totally clear (to me, anyway)
whether this case is covered.

chris@umcp-cs.UUCP (Chris Torek) (08/21/86)

In article <792@navajo.STANFORD.EDU> rokicki@navajo.STANFORD.EDU
(Tomas Rokicki) writes:
>... For example, consider the program:
>
>	int lhs, rhs, index; int *pointers[9];
>	foo() { *( index=lhs, pointers[index] ) = sideeffects(); }
>
>The question is, does C allow for the possibility that the order
>of evaluation might be "index=lhs" then "sideeffects()" then
>"*pointers[index]=<result>"?

No.  The compiler can, however, effectively generate either of the
following:

	temp = sideeffects();
	index = lhs;
	*pointers[index] = temp;

or

	index = lhs;
	tempp = pointers[index];
	*tempp = sideeffects();

>... On the other hand, if C does not allow the compiler to
>generate such code, then the statement is well defined.

Not really, since one sequence sets index=lhs before the call, and
the other after.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

rokicki@navajo.STANFORD.EDU (Tomas Rokicki) (08/22/86)

In article <3047@umcp-cs.UUCP>, chris@umcp-cs.UUCP (Chris Torek) writes:
> In article <792@navajo.STANFORD.EDU> I write:
> >
> >	int lhs, rhs, index; int *pointers[9];
> >	foo() { *( index=lhs, pointers[index] ) = sideeffects(); }
> >
> >The question is, does C allow for the possibility that the order
> >of evaluation might be "index=lhs" then "sideeffects()" then
> >"*pointers[index]=<result>"?
>
> No.  The compiler can, however, effectively generate either of the
> following:
> 

Can someone second this, or show me the appropriate reference?
It's Microsoft 4.0 that's putting the sideeffects() call between
the two parts of the comma expression, and sideeffects() modifies
index . . . you get the idea.  I could find nothing in K&R, but
I'm only been hacking C for a year or so.

I just tested under 4.3bsd; cc also puts the sideeffects() in the
middle.  Comments, anyone?

Thanks!   -tom

tainter@ihlpg.UUCP (Tainter) (08/25/86)

> In article <3047@umcp-cs.UUCP>, chris@umcp-cs.UUCP (Chris Torek) writes:
> > In article <792@navajo.STANFORD.EDU> I write:
> > >	int lhs, rhs, index; int *pointers[9];
> > >	foo() { *( index=lhs, pointers[index] ) = sideeffects(); }
> > >The question is, does C allow for the possibility that the order
> > >of evaluation might be "index=lhs" then "sideeffects()" then
> > >"*pointers[index]=<result>"?
> > No.  The compiler can, however, effectively generate either of the
> > following:
> Can someone second this, or show me the appropriate reference?
> It's Microsoft 4.0 that's putting the sideeffects() call between
> the two parts of the comma expression, and sideeffects() modifies
> index . . . you get the idea.  I could find nothing in K&R, but
> I'm only been hacking C for a year or so.
> 
> I just tested under 4.3bsd; cc also puts the sideeffects() in the
> middle.  Comments, anyone?
> 
> Thanks!   -tom

As far as I can tell the only restriction on order of evaluation is 
index=lhs before pointers[index].
Lets meta a bit:
*(a,b)= c;
can be evaluated:
c a b
a c b
a b c
If c plays with something also played with in a or b then you are in the
same boat as the people counting on order of evaluation in:
*a++ = *a + gunga_din;

--j.a.tainter

chris@umcp-cs.UUCP (Chris Torek) (08/26/86)

>>>	foo() { *( index=lhs, pointers[index] ) = sideeffects(); }
>>>... does C allow for the possibility that the order
>>>of evaluation might be "index=lhs" then "sideeffects()" then
>>>"*pointers[index]=<result>"?

>In article <3047@umcp-cs.UUCP> I wrote:
>>No.

In article <2401@ihlpg.UUCP> tainter@ihlpg.UUCP (Tainter) writes:
>As far as I can tell the only restriction on order of evaluation is 
>index=lhs before pointers[index].

After more thought, I now reverse myself.  K&R (p. 192) say only
`a pair of expressions separated by a comma is evaluated left-to-
right and the value of the left expression is discarded.'  Apparently
this does not imply that nothing else may occur in between.  I may
see whether X3J11 is more explicit, but that must wait until I am
once again near a copy of the latest draft.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu