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".