[net.lang.c] order of evaluation parse date s

mcewan (02/27/83)

#R:houxj:-22000:uiucdcs:27600008:000:271
uiucdcs!mcewan    Feb 26 21:47:00 1983

    i = 4;
    i = i++;
    printf ("%d\n", i);

----------

Clearly, the value of "i++" is 4. However, c does not specify whether the
increment or the assignment is done first, so the value of i after this
statment is UNDEFINED, or, if you prefer, "compiler dependent".

johnl (02/27/83)

#R:houxj:-22000:ima:15900002:000:735
ima!johnl    Feb 26 12:53:00 1983

Re: table[i++] = ++i;

The term "expression" in K&R refers to the entire expression (remembering
that = is syntactically just an operator.)  Ergo, the compiler can
legitimately fool with both of the ++ operators.

If there's ever going to be an ANSI C standard, we'll have to straighten
this sort of thing out.  A while ago I posed a similar problem:

	a = foo(i++);

asking whether the ++ has to be done before foo() is called.  Strictly,
K&R doesn't appear to require it, but in practice many programs assume that
it is, so real compilers usually do so.  (And please don't send out your
opinion on the right thing to do; we beat this dead horse already.)

John Levine, decvax!yale-co!jrl, ucbvax!cbosgd!ima!johnl, research!ima!johnl

preece (03/01/83)

#R:houxj:-22000:uicsl:6400003:000:475
uicsl!preece    Feb 28 12:42:00 1983

I just noticed that my remarks are really aimed at a response
to the base note (which itself mentionend pg50 of K&R). Sorry.

I think my response to the base note (which looked at the
expression table[i++]=i++ and asked if the compiler was allowed
to evaluate part of one expression, then part of another, then
the rest of the first, then the rest of the second) is that the
whole thing is one expression, not two, and therefore can be
evaluated in any order.

scott preece

alb (03/03/83)

i = 4;
i = i++;

Regardless of whether the increment of the assignment comes first,
i == 5 afterwards.  Think:

If the increment comes first:
i++ (so i == 5)
i = i (so i == 5)

If the assignment comes first:
i = i (so i == 4)
i++ (so i == 5)

dmmartindale (03/09/83)

It isn't necessarily true that i == 5 after executing i = 4; i = i++;
Consider the following code sequence for i=i++ on a hypothetical machine:

	lda	i	# load i into accumulator
	aos	i	# do post-increment with Add One to Storage instruction
	sta	i	# and then store back into i

At the end, i == 4.
This is a perfectly reasonable code sequence to generate on a machine
that has no two-operand instructions, but does have an "aos" instruction.
Moral: Never try to second-guess the compiler and hardware when the result
is not defined by the semantics of the language.

	Dave Martindale

wagner (03/10/83)

We seem to be confusing several different things all into one big basket
here.  There are several cases when C is allowed to re-arrange things,
and we seem to be lumping some of them together.  First off:
1) In a private communication, Dave Martindale told me (I hope he doesnt
   mind me quoting him "on the air" that the expression
   foo(++i,++i) could pass 3 different sets of parameters to foo; i.e., if
   i was zero before we started, foo could get passed
   1,2
   2,1
   or
   2,2
   and the decision was up to the compiler.  The relevant quote here is
   "The order of evaluation of arguements [to functions] is undefined by
   the language; take note that the various compilers differ".
   In talking with others around here, it seems the issue boils down to
   whether the increment/decrement operators are indivisible or not.  I 
   suspect that there is room for a fourth option; foo could get passed
   1,1 if each subexpression first picked up the current value of i into
   a different private register, then each private register was incremented,
   then each was stored back into the memory location for i, then the value
   was passed to foo.  The order of evaluation of arguments is undefined...
   but are we guaranteed that all of one is finished before another starts,
   or are we open to "race" conditions?  This may well become important when
   multiprocessors become more popular.
2) Someone in news today said that the sequence
   i=4;
   i=i++;
   would always equal 5; this I believe to be incorrect.  The action of i++ is
   a) copy the value of i to a safe place
   b) increment i
   c) the result of the subexpression i++ is the value in the safe place.
   Point (c) above implies that the result assigned to i would be 4.
   In the case i=++i, i is (almost) trivially 5, since the expression
   simplifies to i=i+1, with little chance for confusion.
3) Several people have said that C expressions may be rearranged arbitrarily;
   that is not true.  There are still rules of precedence and so on.  
   Subexpressions may be computed in any order, even in the face of side
   effects, and the order of operands to binary *, +, &, | and ^ can be
   shuffled.

This is all very fascinating, and I have spent several hours going through
K&R to try to sort all this out, but I think anyone who relied on any of
these things, even in a language which claimed to have more rigidly
defined order of evaluation, would be coming up with code which was unreadable
by a human, even if the compiler did promise to sort it out.

Michael Wagner, UTCS

msc (03/10/83)

	I have listened to the discussion about the order
	of evaluation of expressions and the areas which can vary
	from compiler to compiler.

	There is a very entertaining little book whose intention is
	to point up these and other fun areas of C.  It is called

		"The C Puzzle Book"
		Alan R. Feuer
		Prentice-Hall, Englewood, N.J., 1982

	I recommend it highly to anyone who is investigating some
	of the intricacies of C and to anyone who likes brain-teasers.

			Mark Callow
			Qubix Graphic Systems
			...decvax!decwrl!qubix!msc
			...ucbvax!ucscc!qubix!msc

preece (03/12/83)

#R:houxj:-22000:uicsl:6400004:000:1052
uicsl!preece    Mar 11 08:28:00 1983

***** uicsl:net.lang.c / alice!e /  3:46 pm  Mar  3, 1983
i = 4;
i = i++;

Regardless of whether the increment of the assignment comes first,
i == 5 afterwards.  Think:

If the increment comes first:
i++ (so i == 5)
i = i (so i == 5)

If the assignment comes first:
i = i (so i == 4)
i++ (so i == 5)
---------
Think again:
	Stack old value of i
	Store incremented value in i
	Pop stacked (old) value into i (so i == 4)

This is a perfectly reasonable interpretation, given that the whole
line (i = i++) is one expression, and therefore re-arrangeable.
In fact, many would say it's the RIGHT way, since it means the
result of 'a = i++' and 'i = i++' are the same.

Clearly K+R says they're all right methods, and the author should
avoid ambiguous expressions.

[I agree with most of you out there that this topic has had
enough attention, but i also think it's worthwhile to keep
addressing mis-interpretations in the hopes of as many readers
as possible understanding the problem and avoiding such usage.]

scott e preece
uiuc coordinated science lab

preece (03/13/83)

#R:houxj:-22000:uicsl:6400005:000:1091
uicsl!preece    Mar 12 14:31:00 1983

No. Sorry, but I think mine is a reasonable human interpretation
and, in fact, that's the way I'd like the computer to be required
to reach (that is, i'd really like the assignment operator to
force its right side to finish up before assigning). My argument
is as given before:
	a = i++
and
	i = i++
really ought to result in their left-hand sides being the
same. That's an argument from human interpretation, not machine
internals. I suspect it's also compatible with the original
machine purpose of the ++ form, which was to take advantage of
special pdp-11 addressing mode that increments after fetching
the contents of a register; thus they were intended to leave
the incremented value in the variable immediately after obtaining
the old value, not at the end of expression evalutation.

The book is clear - the implementor can do it any way convenient.
And anyone writing the line of code i = i++ deserves to not
know exactly what's going to come out. And anyone writing C code
should be aware that order of evaluation is not controllable.

scott e preece
uiuc coordinated science lab

donchin (03/14/83)

#R:houxj:-22000:uiucdcs:27600012:000:460
uiucdcs!donchin    Mar 11 21:56:00 1983

The rethinking in the last note is of an entirely different form
from the thoughts in the response it addressed.  The original argument
(that the resulting value for i should be 5) was looking at
the question from a high level point of view.  He was showing that
the two reasonable human interpretations for the expression both
yeild the same result, and the computer interpretation should be
made to conform.  Regardless of how the computer works internally.

mark (03/16/83)

#R:houxj:-22000:zinfandel:14600004:000:1416
zinfandel!mark    Mar 10 11:28:00 1983

Michael Wagner has a very good point: readability by humans.
When I run across like that being discussed here I have to decide:

	1. How does this code work on the machine for which the
	   author wrote it?
	2. How does it work on the machine(s) on which I intend
	   to run it?
	3. If they are different does it matter?
	4. If it matters, is it
		a. necessary (eg, fix differences in the machines)
		b. a "feature" (ie, can be tolerated)
		c. a "bug" (ie, must be fixed)
	5. Did the author consider any or all of (1)-(5)?
	6. If so, do I think s/he was correct on all of them?
	7. If not, am I missing something or is the author?
	8. If the author didn't consider all of the points, or was wrong
	   on some of them, how closely should I look at the rest
	   of the code for other non-portable constructs?

In other words, even if the code works probably on all existing and known
machines and compilers I have to waste a lot of time on the code,
even if it turns out to be ok.

I don't care if the compiler can sort things out if people can't;
such features should be used, even when portable, without a very
compelling reason.

Mark Wittenberg
...!decvax!sytek!zehntel!mark


PS.  I can't think of any compelling reasons for the examples mentioned here.
PPS. I also don't like use of ADA overloading for similar reasons;
     please direct all flames to /dev/null, as I don't want to start
     ADA debates here.