Path: utzoo!mnetor!uunet!husc6!bloom-beacon!tut.cis.ohio-state.edu!mailrus!ames!umd5!mimsy!chris From: chris@mimsy.UUCP (Chris Torek) Newsgroups: comp.lang.c Subject: Re: strcpy specifications Message-ID: <11034@mimsy.UUCP> Date: 12 Apr 88 15:24:34 GMT References: <7712@apple.Apple.Com> <7485@brl-smoke.ARPA> <10731@mimsy.UUCP> <4383@ihlpf.ATT.COM> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Lines: 121 I am not going to respond to the whole thing, for I am getting quite sick of this debate. `>>' below is mine, `>' is Nevin: In article <4383@ihlpf.ATT.COM> nevin1@ihlpf.ATT.COM (00704a-Liber) writes: >>[optional def. 2] copies string `src' to `dst' nondestructively. >This one can never be right, since some types of overlap are destructive. It is `right' in the same sense that it is `right' to describe memmove(src, dst, len) as `nondestructive'. >>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?? If `src' and `dst' point to different objects, they cannot overlap, and there is no question as to interference. If `src' and `dst' *do* point to places within the same object---e.g., char buf[1000]; src = &buf[0]; dst = &buf[500]; ---then the two pointers can be meaningfully subtracted, so the condition is simply `src < dst'. In other words, yes, the pointers should simply be subtracted, as long as it is meaningful to do so. >Since you are (thoretically, anyway) trying to define a standard, please be >more precise with your terms. I might if I thought anything might come of this. >>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! Yes. You may have noticed that I was working from least to most concrete [possibly with definitions 0 & 1 reversed]. The absolute most concrete definition is to say `this library function shall be implemented by the following C code'---that pins the semantics of the routine down as firmly as they may ever be pinned (providing, of course, that you have already defined the actions of the various statements). I was merely trying to show (with the `overlap' definitions 2, 3) that one can be less concrete and still make claims about overlapping copies. >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. The properties of the `while' statement were defined back in section three. Why should I repeat them? But this *is* an implemetational specification, although there is an escape clause (the `as if' rule). >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). Yes. >If this were added to the Standard, then the whole of Case IV would >start being relied upon, Quite possibly. >and this would just lead to horrible programming styles!! That remains to be demonstrated. >>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; [which definition? I think he means 3] >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. [now he probably means 4, but more generally:] What makes this an abuse, beyond the fact that right now *your* manual entry (but not mine!) says so? Why is this *inherently* wrong? The facts: - There exists code now that looks like this: char buf[SIZE]; ... if (buf[0] == '/') /* remove the leading slash */ (void) strcpy(buf, buf + 1); - According to the current draft, this operation is `implementation defined'. - There are no known implementations in which this does anything other than what the comment in the above code suggests. - Hence, making this particular action well-defined would affect no known implementations, but would make the code above portable. Opinions: - This intended action of that code is a reasonable thing to want. (`char *bp; bp = buf[0]=='/' ? buf+1 : buf' will usually be faster and cleaner, but may be contraindicated for some other reason.) - Defining strcpy such that this operation is well-defined is a reasonable thing to do. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris