strcpy specifications

Chris Torek chris at mimsy.UUCP
Wed Apr 13 01:24:34 AEST 1988


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 at ihlpf.ATT.COM> nevin1 at 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 at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list