Thanks, everyone, for the additional remarks, and I can see
I should give up my habit of "shifting left" (squeezing out
substrings of) strings using strcpy.
But the above example's giving me a little problem. For strcpy
to "work under some circumstances", the compiler has to add
extra instructions to check the input strings and choose how to
proceed accordingly. The parenthetical example above needs to
determine strlen before proceeding. That's a lot of overhead.
I'd imagine so much overhead that any optimization gained by using,
say, one method for short strings and another for long ones would be
more than wiped out.
Quite often, some unusual optimizations "fall out" along the way.
For example, lots of implementations of string functions try to work
in bigger-than-char units if possible: If you can copy eight chars
per loop iteration instead of one, for example, you may gain enough
speed to make up for a more complicated loop. It's quite possible
that a strcpy() might move the first few characters in an obvious
way until the advancing pointers reach nice boundaries, and then
switch to a trickier method to move four or eight or sixteen at a
whack. Exactly what happens when source and destination overlap in
such a case could be very difficult to predict.
Anecdote: I was once doing speed tests on some sorting functions,
and wanted to try them with "fast" and "slow" comparators. My slow
comparator called strcmp(long_string, long_string) to waste some time,
and during initialization I'd adjust the length of long_string to make
the slow comparator take ~10 times as long as the fast one. All was
well -- until I tried my program on a previously-unmeasured O/S and it
ran out of memory during initialization. Poking around a bit, I found
that it was trying to grow long_string beyond the total size of memory,
because strcmp(long_string, long_string) was too fast ...
Yes, friends, the strcmp() implementation noticed that a string was
being compared to itself, and returned zero in constant time without
actually looking at the string's characters. The test sounds like a
time-waster (how often would a sane programmer call strcmp() with two
identical pointers?), but upon investigation I found that it pretty
much fell out of other tests that were being done to decide how many
characters strcmp() could gulp at a time. I switched my time-waster
to strcmp(long_string, long_string+1) and all was well.