> I said "points into either T or S", not
"points into what either T
> or S points to". That is, "*T = X;" may change S (as opposed to
> changing the memory S points to).
Ah. The rule that permits the compiler to optimize the
long form into
the short here is C89 3.3.16.1:
If the value being stored in an object is accessed
from another
object that overlaps in any way the storage of the first object,
then the overlap shall be exact and the two objects shall have
qualified or unqualified versions of a compatible type; otherwise
the behavior is undefined.
The C99 draft I have contains very similar language in 6.5.16.1 #3, so
similar I don't think it's worth quoting it. ("accessed" becomes
"read", and there's a comma after the last "otherwise".) It's
one of
the constraints on simple assignment.
After a multi-email exchange with my C language lawyer friend, most of
which was us talking past one another because I was misreading that
constraint until he realized how my reading differed from the intended
one, I think it's straightened out, and it isn't relevant here.
To use the modern language, annotated to clarify the understanding I
now have of it, "[i]f the value being stored [in a simple assignment]
in an object is read from [ie, is obtained by reading from] another
object that overlaps in any way the storage of the first object,
[...]". That is, to put it a bit loosely, this is talking about
overlap between the LHS and RHS of the assignment, not overlap between
the LHS of the assignment and some later read of the same object.
Thus, none of the assignments in the long form violate this constraint
and there is no undefined behaviour, or at least not due to that
constraint. This then means the compiler is not justified in moving
the S++ increment across the *T=X assignment, at least not absent some
other reason behaviour is undefined, and on hardware with an
instruction set that permits doing the S++ at the same time as the *S
(VAX, PDP-11, maybe 68k), the short form very well may be more
efficient.
Reinforcing the idea that my reading of that constraint is wrong is
that, when read that way, it means that a char-by-char copy from one
object to another produces undefined behaviour in most cases, and
that's something which is definitely supposed to work. This is why
I've been pretty sure from the start that that reading was wrong; I
just had trouble figuring out _how_ it was wrong.
/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mouse at
rodents-montreal.org
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B