Defect Report #219

Previous Defect Report < - > Next Defect Report


Submitter: Clive Feather (UK)
Submission Date: 2000-04-04
Source:
Reference Document: N/A
Version: 1.2
Date: 2000-04-18 05:10:16
Subject: Effective types

Summary
6.5 reads:

[#6] [...] If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.

Now consider the code extract:

     struct s { char c; int i; long l; double d; } s = { 1, 2, 3, 4 };
     size_t len1 = sizeof (int);
     size_t len2 = offsetof (s, d) - offsetof (s, i));
     void *p1 = malloc (len1); assert (p1);
     void *p2 = malloc (len2); assert (p2);
     memcpy (p1, (char *)&s + offsetof (s, i), len1);
     memcpy (p2, (char *)&s + offsetof (s, i), len2);

What are the effective types of p1 and p2 ? The cited text would imply that they are both struct s, even though this is patently nonsense.


Committee Discussion
Consider:

1. struct s { char c; int i; long l; double d; } s = { 1, 2, 3, 4 };
2. size_t len1 = sizeof (int);
3. size_t len2 = offsetof (s, d) - offsetof (s, i));
4. void *p1 = malloc (len1); assert (p1);
5. void *p2 = malloc (len2); assert (p2);
6. memcpy (p1, (char *)&s + offsetof (s, i), len1);
7. memcpy (p2, (char *)&s + offsetof (s, i), len2);

In lines 6 and 7, the type of the source object in the memcpy is an array of char because the dereference of (char *)&s + ... is a char. This is inferred by:

- "(some_type*)x" has the type "pointer to some_type"
- the dereference of "pointer to some_type" has the type "some_type"

In other words, "(char *)&s + offsetof (s,i)" has type "pointer to char" and its dereference has type "char", i.e., the type of the source object. In the following examples:

8. memcpy (p1, &s.i, len1);
9. memcpy (p1, (char *) &s.i, len1);
10. memcpy (p1, (float *) &s.i, len1);
the source types are, respectively, array of int, char, and float.

In lines 6 and 7, the effective type of the source arguments to memcpy is an array of char, based on the following sentence from 6.5P6:

"For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access."

Based on the following sentence again from 6.5P6:

"If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one."

The object being copied into has no declared type (because it was an allocated object), thus "the effective type of the modified object for that access ... is the effective type of the object from which the value is copied ...". The object from which it was copied is array of char. The effective type for p1 and p2 in lines 6 and 7 is: array of char.


Previous Defect Report < - > Next Defect Report