Subject: Re: main return...
To: None <jfw@FunHouse.com>
From: Objects In Mirror Are Closer Than They Appear <greywolf@defender.VAS.viewlogic.com>
List: current-users
Date: 03/27/1996 16:46:44
   "John F. Woods" <jfw@FunHouse.com> writes:

   It is explicitly forbidden.  And the reason for it has nothing to do with
   order of evaluation.  In between two "sequence points", if you store to an
   object, you may not evaluate the object except to determine the value to be
   stored in that object; you also may not store to an object more than once
   between two sequence points, thus forbidding "i = ++i;".

"i = ++i;" is a lot more ridiculous than "a[i] = i++"; since you're actually
trying to assign to a variable while incrementing it, which is slightly
different than what "a[i] = i++" does (one level of indirection).

This said, I don't necessarily disagree with you on that point.
   
   The standard says the behavior is undefined in both cases, meaning the
   compiler may emit code which does *anything at all*, including enabling
   multiple functional units in a parallel processor on a single bus
   simultaneously burning out the bus driver transistors.

:-) (got a good chuckle out of that last part)

   Even beyond that, your analysis is still flawed:

   > 	[] binds first, left to right, so we have a[i].
   > 	++ binds next, right to left, so i is now i+1.
   > 	= binds last, right to left, so a[i] has the value i+1.

   *when* do you calculate the lvalue a[i]?  Only the binding for = is
   specified, not the order of evaluation.  When does the autoincrement happen?
   "Sometime" before the semicolon, that's all you know.

Well, hell.  According to K&R's table of evaluation order, things get
evaluated from right-to-left with assignment operators last in line; i.e.
things happen to the variables, then the assignment ops go through.

Which, upon re-reading this, means that a[0] should be undefined, and a[1..n]
should get the values 1..n.  Under StunOS and gcc, this doesn't happen --
I see a[0..x] get the values 0..x and it's left at that, which I found
surprising, when it's probably what any first-year C student would expect.

   > (StunOS 4.x standard compiler AND gcc do this -- is this right?).

Meant to say, "...gcc DON'T do this -- is this right?"

   EX-CUSE me, but "it works on my compiler!" has never, EVER been the
   definition of C, not since the introduction of pcc, anyway!  That's what the
   standardization effort is all about!

No argument here.  Just expanding my own knowledge...


   - And weep for the state of education.

   And to emphasize this: "The C Programming Language", by Kernighan and
   Ritchie, has been warning about THIS VERY EXAMPLE since 1978!

   > I don't know a compiler that would reject the code.  Of course, that
   > speaks loudly for the state of education among compiler writers, I
   > suppose...

   The standard permits compilers not to diagnose this, mostly because
   diagnosing all possible cases of violation of this requirement would be
   impossible.

Would it?  If you're taking something which resolves to address X and
try to autoincrement the value at that same address while assigning to
it, it ought to be fairly obvious to catch, since what the example you
first gave boils down to is:

	ax[*(&ay)] = *(&ay)++;

"i = i++;" is even more glaring:

	*(&ay) = *(&ay)++;

[Hmm, I suppose that if the exact address is not in scope it would be
considerably difficult.  Okay, I concede...]

   While a compiler could pick up really obvious cases, presumably
   most compiler writers regard their time better spent adding Dhrystones than
   diagnostics...

Hmmm.  Perhaps the compilers should define the undefined behaviour to
start up "/usr/games/rogue".