It was thus said that the Great Mouse once stated:
> while
(*T++=*S++);
> do
> {
> X = *S;
> *T = X;
> S++;
> T++;
> }
> while('\0' != X);
(obvious fix applied to the condition)
The long version isn't less efficient.
Actually, it is, or at least may be, depending on the compiler; there
certainly are semantic differences between them.
In particular, in the original, there is no sequence point during the
load-store-increment-increment operation, which means the compiler can
make assumptions like "neither T nor S points into either T or S" and
let the undefined behaviour resulting from multiple modifications
between sequence points cover for it if they do. The long version has
sequence points all through it, and, for example, the compiler cannot
assume that T does not point into S and thus S++ cannot be collapsed
with *S.
I don't think you're right about that. I can write, for instance:
void copy(char *t,char *s)
{
while((*t++ = *s++))
;
}
int main(int argc,char *argv[])
{
copy(argv[0],argv[0]);
return 0;
}
C has to assume (well, prior to C99, more on that in a bit) that pointers
it receives point to the same location, otherwise, why have memcpy() and
memmove()? C99 has ways of telling the compiler that the two pointers won't
be aliases of each other:
void copy (char *restrict t,char *restrict s)
{
while(*t++ = *s++)
;
}
copy(argv[0],argv[0]);
I would exepct a C99 compiler to bitch about aliased pointers. Hold on
... wow ... GCC 3.4.6 didn't bitch about that. "splint --strict" kind of
... did:
a.c:9:3: Statement has no effect (possible undected modification through
call
to unconstrained function copy): copy(argv[0], ar...
Statement has no visible effect --- no values are modified. It may modify
something through a call to an unconstrained function. (Use -noeffectuncon to
inhibit warning)
I'm ... um ... surprised at this.
-spc (dismayed is more like it ... )