strcpy specifications

00704a-Liber nevin1 at ihlpf.ATT.COM
Tue Apr 12 11:29:29 AEST 1988


In article <10987 at mimsy.UUCP> chris at mimsy.UUCP (Chris Torek) writes:
>In article <4343 at ihlpf.ATT.COM> nevin1 at ihlpf.ATT.COM (00704a-Liber) writes:
>>You are not defining *what* the function does (ie, you are not making an
>>abstract *description* of the function); you are defining *how* the
>>function does a strcpy (ie, how it is suppose to be *implemented*).

>Nope.  I can define what strcpy should do without saying how it should
>do it:

>    char *strcpy(char *dst, char *src);

>0.  copies string `src' to `dst'.  `src' and `dst' shall not overlap.

As my man page states.

>1.  copies string `src' to `dst'; if src and dst overlap, the result
>    is implementation-defined.

As a few people on the net want it stated.

>2.  copies string `src' to `dst' nondestructively.

This one can never be right, since some types of overlap are destructive.

>3.  copies string `src' to `dst' such that the copy is nondestructive
>    when src and dst are distinct or when src < dst.

By 'src < dst' do you mean 'strlen(src) < sizeof(dst) / sizeof(char)', or
do you mean that the addresses should just be subtracted??  (Assuming you
are talking about the length(dst) instead of address dst, I'm not sure what
you mean by length(dst).  It can't be strlen(dst), since this is
meaningless for a newly malloc()ed block.)
Since you are (thoretically, anyway) trying to define a standard, please be
more precise with your terms.  That's what got us into this trouble in the
first place! :-)

>4.  copies string `src' to `dst'.  By the time strcpy returns, the
>    result is as if the copy were done using the following code:
>
>	while ((*dst++ = *src++) != 0) /*void*/;

Sorry, but this IS defining it in terms of an implementation!  If you were
to define it in terms of what the properties of your 'while' statement is,
then I would be satisfied that your definition is implementation-free.


Just what are the properties of implementing strcpy() as the while loop you
stated above?  Here is the list I came up with:

Case I:		strlen(src) < abs(src - dst)

This is the non-destructive strcpy() that we all know and love.   :-)

Case II:	0 < dst - src <= strlen(src)

This is an infinite loop which trashes memory starting at location dst.

Case III:	src == dst

Nothing happens except for a few lost CPU cycles.

Case IV:	0 < src - dst <= strlen(src)

This is the DESTRUCTIVE strcpy().  When done, the array src[] is the string
which was formerly pointed to by 2 * src - dst.


Now, ask yourself a question.  Wouldn't it be nice to tell the difference
between someone using strcpy() for a non-destructive use instead of using
strcpy() for this VERY SPECIALIZED destructive use (as given in Case IV)??
Personally, there are very few times that I need or want to change the src
string AND the dst string in this manner at the same time (none that I can
think of).  And those few times that I need to do both of these at the same
time I would rather call a different function, for the sake of readability
and maintainability.  But, if this is added to the Standard, then strcpy()
should always be used when Case IV destructive copies are needed as well as
when Case I non-destructive copies are needed.

>From what I understand, a degenerate of Case IV is currently being relied
upon (ie, destructive copies where the programmer doesn't care about what
happens to the src string).  If this were added to the Standard, then the
whole of Case IV would start being relied upon, and this would just lead to
horrible programming styles!!

>As general design principles, let me offer these statements:
>  - provide as few primitives as you can get away with;
>  - make them as general as possible.

I agree.  However, it is worth adding a not-so-general primitive if it will
be used a lot and/or it's efficiency can be significantly improved (such as
having printf() as well as the more general fprintf()).

>I think allowing overlapping strings in
>strcpy carries its weight better than does asking people to use
>memmove(dst, src, strlen(src)).

But you don't allow all types of overlapping strings with your primitive;
only a very special subset of overlapping strings (where src >= dst).  And
by adding this to the Standard, you also allow an abuse of strcpy() when it
is used specifically to modify the src string.
-- 
 _ __			NEVIN J. LIBER	..!ihnp4!ihlpf!nevin1	(312) 510-6194
' )  )				"The secret compartment of my ring I fill
 /  / _ , __o  ____		 with an Underdog super-energy pill."
/  (_</_\/ <__/ / <_	These are solely MY opinions, not AT&T's, blah blah blah



More information about the Comp.lang.c mailing list