Portability of some overlapping strcpy or memcpy calls

Mark H. Colburn mark at jhereg.Jhereg.MN.ORG
Fri Mar 10 12:20:22 AEST 1989


In article <338 at wjh12.harvard.edu> kendall%saber at harvard.harvard.edu (Samuel C. Kendall) writes:
>Consider the following function call:
>
>	memcpy(p, p + M, N)
>
>where p is a char*, M is nonnegative, N is positive, and M < N.  This
>is an overlapping copy, where the bytes are being copied to the left (M
>> 0) or onto themselves (M == 0).  I am interested in finding out if
>this call to memcpy, and similar calls to memccpy, strcpy, and strncpy,
>are portable.

This is not particularly portable.  There are some problems with
overlapping on some impementations.

>I'm interested in practical portability, not theoretical.  This call is
>obviously illegal, since overlapping copies are forbidden by ANSI and
>by the Unix man pages I've seen.  However, the copy succeeds in all the
>implementations I've tested (Sun, Vax), and it makes sense -- you have
>to go out of your way to make this kind of overlap fail.  If someone
>knows of an implementation where it does fail, please let me know which
>implementation it is and how it fails BY MAIL.  I'll summarize to the
>net if anyone shows interest.

The ANSI standard does not forbid the call, it just says that the results
of the operation on overlapping strings is undefined (read non-portable).
The reason for this, obviously, is that some implementation do not support 
overlapping data on these calls.

There is however, another function which is garaunteed to work with
overlapping data: memmove().

>Details: how could this call fail to copy correctly?  The
>implementations I know copy left-to-right.  An implementation that
>copied right-to-left would definitely fail.  Also, an implementation
>that copied in larger-than-byte units, and which couldn't handle
>overlapping units, would fail for small M.  Finally, an implementation
>with run-time checking for this condition would fail.

It would failt to copy correctly if it copies left to right and the strings
look like this in memory (string 1 is the source, string 2 the destination):


	[----- string 1 -------]
	      [------- string 2 -------]

As you could see, the first character of the string, when moved would
destroy other stuff in  at by the string.  Conversely, if it copies
right to left:

		[----- string 1 -------]
	    [------ string 2 -----]

Overlapping copies must check to see if there is a possibility that the
data would collide when copied, and then choose the correct direction to
copy.  It is not all that hard, but it takes time.  It also may make things
slightly more obtuse, but standards generally do, in the name of
portability.

Attempting to find that all impementations really support a strcpy or
memcpy which handles overlapping data is, quite honestly, a waste of time.
It is not portable, why bother finding out that most all implementations
support it?  Would you then use it?  It will break on some machine, most
likely during your most important demo...  Why bother?

-- 
Mark H. Colburn                  "Look into a child's eye;
Minnetech Consulting, Inc.        there's no hate and there's no lie;
mark at jhereg.mn.org                there's no black and there's no white."



More information about the Comp.lang.c mailing list