Path: utzoo!mnetor!uunet!lll-winken!lll-lcc!ames!mailrus!tut.cis.ohio-state.edu!osu-cis!att-cb!att-ih!ihnp4!ihlpf!nevin1 From: nevin1@ihlpf.ATT.COM (00704a-Liber) Newsgroups: comp.lang.c Subject: Re: strcpy specifications Message-ID: <4383@ihlpf.ATT.COM> Date: 12 Apr 88 01:29:29 GMT References: <7712@apple.Apple.Com> <7485@brl-smoke.ARPA> <10731@mimsy.UUCP> <4343@ihlpf.ATT.COM> <10987@mimsy.UUCP> Reply-To: nevin1@ihlpf.UUCP (00704a-Liber,N.J.) Organization: AT&T Bell Laboratories - Naperville, Illinois Lines: 104 In article <10987@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: >In article <4343@ihlpf.ATT.COM> nevin1@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." / (_