Implementation-DEPENDENT code (was:strcpy)

Jim Patterson jimp at cognos.uucp
Fri May 6 03:46:56 AEST 1988


In article <6743 at bellcore.bellcore.com> sjs at spectral.UUCP (Stan Switzer) writes: 
>... all known implementations implement strcpy(s,d) s.t. when s and d 
>overlap and s < d, the copy is non-destructive. This is the essential point.  
>My point still stands that 
> 1) in all known implementations it "does the right thing"

The SUN 3 implemention doesn't, or at least not by your definition. I
suspect other implementations on architectures that don't have complex
instructions like MOVC3 won't implement strcpy non-destructively
either. Generally it will be implemented "left-to-right" which of
course is destructive in some instances.

>3) there is no known reason why on any implementation it could be 
>inefficient to require this semantics (and considerable reason to 
>doubt that it ever could be more inefficient, given that you would have 
> to count 'd' first anyway).

You DON'T have to count 'd'.  strcpy can just copy until it encounters
the NUL.  Following is a portable (but potentially destructive) strcpy
implementation.  It doesn't know (and doesn't care) what the length of
the string is. Sun's implementation is essentially this and does the
copy via a three instruction loop (it appears that two instructions
would do on the 68000).

strcpy(a,b) char *a, *b; {
   while (*a++ = *b++)
     ;
 }

Implementing strcpy as you suggest would burden all of its users with
the overhead of passing over the source string twice. Except for those
few applications which depend on a non-destructive implementation, one
of these passes is wasted cycles.

The ANSI committee encountered an analagous situation with memcpy
which also is non-destructive on typical VAX implementations but
destructive on many other implementations. It was resolved by adding
another function, memmove, which is guaranteed non-destructive but
will likely be less efficient. memcpy can often be effectively
implemented as inline code (which DG has done in their compiler), but
the VAX is the only architecture I'm aware of where it would be
reasonable to implement memmove inline (DEC didn't bother to however).
Even systems with microcoded block move instructions don't usually
implement them non-destructively as VAX has (look at IBM 370 or DG MVs
as examples), so you still need to at least compare the source and
target addresses when implementing memmove. The necessarily less
efficient implementation possibilities likely had a bearing on the
ANSI decision in this case.

Perhaps your problem could be resolved by also adding strmove (and of
course strnmove). Note that the additional cost of memmove over memcpy
is quite a bit less than that of the hypothetical strmove over strcpy,
since strmove must in typically half of the cases compute the length
of its source first.
-- 
Jim Patterson                              Cognos Incorporated
UUCP:decvax!utzoo!dciem!nrcaer!cognos!jimp P.O. BOX 9707    
PHONE:(613)738-1440                        3755 Riverside Drive
                                           Ottawa, Ont  K1G 3Z4



More information about the Comp.lang.c mailing list