Defect Report #042
Submission Date: 10 Dec 92
Submittor: WG14
Source: X3J11/92-001 (Tom MacDonald)
Question 1
The description of memcpy in subclause 7.11.2.1 says:
void *memcpy(void *s1, const void *s2, size_t n);
The memcpy function copies n characters from the
object pointed to by s2 to the object pointed to by s1.
If copying takes place between objects that overlap, the behavior
is undefined.
The definition of the term object in subclause 3.14 is:
object - A region of data storage in the execution
environment, the contents of which can represent values. Except for
bit-fields, objects are composed of contiguous sequences of one or
more bytes, the number, order, and encoding of which are either explicitly
specified or implementation-defined. When referenced, an object may
be interpreted as having a particular type...
Are the objects in the description of memcpy the largest objects
into which the arguments can be construed as pointing?
In particular, is the behavior of the call of memcpy in Example
1 defined:
void f1(void) {
extern char a[2][N];
memcpy(a[1], a[0], N);
}
because the arguments point into the disjoint array objects, a[1]
and a[0]? Or is the behavior undefined because the arguments
both point into the same array object, a?
Response
From subclause 3.14, an object is ``a region of data storage ...
Except for bit-fields, objects are composed of contiguous sequences
of one or more bytes, the number, order, and encoding of which are
either explicitly specified or implementation-defined ...'' From
subclause 7.11.1, ``the header <string.h> declares one type
and several functions, and defines one macro useful for manipulating
arrays of character type and other objects treated as arrays of character
type.'' ``Various methods are used for determining the lengths
of the arrays...'' From subclause 7.11.2.1, description of memcpy,
``if copying takes place between objects that overlap, the behavior
is undefined.'' Therefore, the ``objects'' referred to by
subclause 7.11.2.1 are exactly the regions of data storage pointed
to by the pointers and dynamically determined to be of N bytes
in length (i.e. treated as an array of N elements of character
type).
- So, no, the objects are not ``the largest objects into which
the arguments can be construed as pointing.''
- In Example 1, the call to memcpy has defined behavior.
- The behavior is defined because the pointers point into different
(non-overlapping) objects.
Question 2
For the purposes of the description of memcpy, can a contiguous
sequence of elements within an array be regarded as an object in its
own right? If so, are the objects in the description of memcpy
the smallest contiguous sequences of bytes that can be construed as
the objects into which the arguments point?
In Example 2:
void f2(void) {
extern char b[2*N];
memcpy(b+N, b, N);
}
can each of the first and last half of array b be regarded as
an object in its own right, so that the behavior of the call of memcpy
is defined? (Although they are not declared as separate objects, each
half does seem to satisfy the definition of object quoted above.)
Or is the behavior undefined, since both arguments point into the
same array object b?
In Example 3:
void f3(void) {
void *p = malloc(2*N); /* Allocate an object. */
{
char (*q)[N] = p; /* The object pointed to by p may
be interpreted as having type
(char [2][N]) when referenced
through q. */
/* ... */
memcpy(q[1], q[0], N);
/* ... */
}
{
char *r = p; /* The object pointed to by p may
be interpreted as having type
(char [2*N]) when referenced
through r. */
/* ... */
memcpy(r+N, r, N);
/* ... */
}
}
the types of the objects are inferred from the pointers, and the underlying
storage is dynamically allocated. Is the behavior of each call of
memcpy defined?
Since the relationship between the values of the arguments presented
to memcpy is the same in all the above calls, it seems reasonable
to expect that either all these calls of memcpy give defined
behavior, or none do. But which is it?
Response
- Yes, for memcpy, a contiguous sequence of elements within
an array can be regarded as an object in its own right.
- The objects are not the smallest contiguous sequence of bytes
that can be construed; they are exactly the regions of data storage
starting at the pointer and of N bytes in length.
- Yes, the non-overlapping halves of array b can be regarded
as objects in their own rights.
- The behavior (in Example 2) is defined.
- The definition of object is independent of the method
of storage allocation. The array length is determined by ``various
methods.'' So, yes, the behavior of each call of memcpy is
well-defined.
- All of the calls of memcpy (in Example 3) give defined
behavior.
Question 3
Similar questions arise for the other library string handling functions
that have undefined behavior when copying between overlapping objects.
These include strcpy, strncpy, strcat, strncat,
strxfrm, mbstowcs, wcstombs, strftime, vsprintf,
sscanf, and sprintf. For these functions, however, the
number of bytes referenced through each pointer depends, at least
in part, upon the values stored in the bytes.
Consider a library function for which the number of bytes accessed
or modified is affected by the values of the bytes. Is the object
associated with each of its pointer arguments the smallest contiguous
sequence of bytes actually accessed or modified through that pointer?
In Example 4:
void f4(void) {
extern char b[2*N];
strcpy(b+N, b);
}
is the behavior defined if N >> strlen(b)?
In Example 5:
void f5(void) {
extern char c[2*N];
strcat(c+N, c);
}
is the behavior defined if both N >> strlen(c) and N >> strlen(c)
+ strlen(c+N)?
Response
Length is determined by ``various methods.'' For strings in
which all elements are accessed, length is inferred by null-byte termination.
For mbstowcs, wcstombs, strftime, vsprintf,
sscanf, sprintf and all other similar functions, it was
the intent of the C Standard that the rules in subclause 7.11.1 be
applicable by extension (i.e., the objects and lengths are similarly
dynamically determined). The behavior (in Examples 4 and 5) is defined.
Previous Defect Report
< - >
Next Defect Report