Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| Path | csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!eternal-september.org!feeder.eternal-september.org!news.swapon.de!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail |
|---|---|
| From | Wojtek Lerch <wojtek_l@yahoo.ca> |
| Newsgroups | comp.std.c |
| Subject | Re: Tracking and Reporting Effective Type |
| Date | Tue, 15 Jan 2013 00:28:03 -0500 |
| Lines | 149 |
| Message-ID | <alk7j2Fb7lqU1@mid.individual.net> (permalink) |
| References | <kcovdt$1ef$1@dont-email.me> <alhgt2Fme55U1@mid.individual.net> <kd0732$q7v$1@dont-email.me> |
| Mime-Version | 1.0 |
| Content-Type | text/plain; charset=ISO-8859-1; format=flowed |
| Content-Transfer-Encoding | 7bit |
| X-Trace | individual.net ux5kvyipkyN4WCFw7EgnGQgys4mvBw9KbH9Dal738JmANYZBPzttpFIDl6jksnvu0i |
| Cancel-Lock | sha1:1xaRj7r5Zco8JArYQp5vKGuDvbw= |
| User-Agent | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130107 Thunderbird/17.0.2 |
| In-Reply-To | <kd0732$q7v$1@dont-email.me> |
| Xref | csiph.com comp.std.c:1836 |
Show key headers only | View raw
On 14/01/2013 1:03 AM, Shao Miller wrote:
> On 1/13/2013 23:48, Wojtek Lerch wrote:
>>
>> union u {
>> struct sl { int16_t s; int32_t l; } sl;
>> struct ls { int32_t l; int16_t s; } ls;
>> uint32_t u;
>> float f;
>> };
>>
>> int main(void) {
>> void *p;
>> if ( sizeof(union u) == 6 // no padding
>> && ( p = malloc(6) ) != NULL ) {
>> union u u;
>> memset( u, 0, 6 );
>> memcpy( p, (void*)&u.sl, 6 );
>> ...
>> }
>> }
>>
>> At the "...", does the 6-byte object that p points to have an effective
>> type? Is it union u, struct sl, or perhaps struct ls? Would the answer
>> change if the second argument of the memcpy were (void*)&u instead of
>> (void*)&u.sl? Or (void*)&u.f?
>
> Assuming you meant 'memset( &u, 0, 6 );',
Indeed I did, thank you.
> I think I saw something like this in Defect Report #219.
That's a good find, thanks. But there seems to be an inconsistency
between the "committee Discussion" (which I believe is non-normative)
and the "Committee Response" (which is normative) about the treatment of
character types.
The DR clarifies one important thing though: it's not only objects named
in declarations that have a "declared type", but also their subobjects,
such as members or elements. But that's the case, then it's still not
clear to me what happens when a compound object and its element or
member, or two members of a union, are exactly the same object. It
would make sense to me that the object might have several declared types
at the same time, but the standard's discussion of effective types
doesn't create the impression that that was considered a possibility,
does it?
> I think that the effective type is indeed 'struct sl' due to the
> declared type of the only lvalue in sight in the 'memcpy': 'u.sl'. I do
> think the answer would change.
But that lvalue is never used to access the object -- its only role is
to produce a pointer to the first byte of the object. The pointers
(char*)&u and (char*)&u.sl point to the same byte, right?
Imagine that u is a union of two different structures x and y, and it
happens that u.x.r and u.y.s have the same offsets and sizes. Would you
claim that
memcpy( p, (char*)&u + offsetof(struct x, r), sizeof(u.x.r) );
and
memcpy( p, (char*)&u + offsetof(struct y, s), sizeof(u.y.s) );
copy different effective types into p, even if they pass exactly the
same values to memcpy?
Remember that an object is just a region of storage; when we talk about
its type, that's just a short way of talking about types of lvalues, or
declared types, or effective types.
Back to my original example, what if I used &u.sl.s in the memcpy? Do
you think the effective type of my allocated object would be int16_t?
Or an array of three int16_ts? Something else? Or do you think such a
memcpy() would be invalid?
>> Does the four-byte sub-object at the beginning of "u" have an effective
>> type?
>
> I'd say each of the 4 bytes would be 'unsigned char', due to the
> 'memset' copying as an array of 'unsigned char', but the effective type
> of the whole would be 'union u', due to the lvalue '&u' in the 'memset',
> and the fact that all bytes were populated.
You explained four one-byte objects and one six-byte object. But what
about my four-byte object that can (I hope) be accessed using such
lvalues as u.ls.l, u.u, and u.f?
>> Is it int32_t, uint32_t, or perhaps (if sizeof(float)==4) float?
>
> If I understand a point from DR #219, the bytes "can be treated" as
> these others,
Is the "can be treated" supposed to mean that an object can have more
than one effective type at the same time? I wouldn't mind that, but I
would prefer some normative text to say it a little more clearly.
> but could be a trap representation for a 'float'.
My concern (for now) is not about the contents of the object but about
its effective type. In particular, the "sticky" kind of effective type
that can conflict with read accesses using an lvalue with the wrong
type, and gets propagated by memcpying to other typeless objects. In
other words, whether one of the standard's statements about the
effective type "for subsequent accesses that do not modify the value"
apply to it or not.
>> Or somehow all of the above?
>
> I don't think so, for tracking and reporting purposes.
>
>> What about the four-byte object starting
>> at the byte that p points to?
>
> I'd say no. The 4 bytes so happen to be correctly aligned and contain a
> correct representation for some of the other members, though.
Sure, but do they have an effective type? The definition of the
effective type does not refer to alignment or contents -- it seems to be
based only on the types of lvalues used for accesses, and effective
types of objects that contents are copied from.
Hey, here's another one:
#define N sizeof(float)
float x = 1.0;
char y[ N ];
float *p = memcpy( malloc(N), memcpy( y, &x, N ), N );
// Does *p have a "sticky" effective type now? Is it char or float?
float z = *p; // Is this valid?
> But if "provenance" was tracked, I'd track it to 'u.sl'; there'd be an
> 'int16_t' and an 'int32_t'. So I might trap '((union u *) p)->ls.l',
> for example, but not '((union u *) p)->sl.s' or '((struct sl *) p)->l'.
What about the examples using offsetof and sizeof? Are we tracking the
provenance of integers now?
>> And the two-byte object starting at the
>> same byte?
>
> I'd say yes, as that'd have the effective type of 'u.sl.s'; 'int16_t'.
> What do you think?
I don't know. I still find the standard's explanation of effective
types hopelessly unclear.
Back to comp.std.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Tracking and Reporting Effective Type Shao Miller <sha0.miller@gmail.com> - 2013-01-11 07:09 -0500
Re: Tracking and Reporting Effective Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-13 23:48 -0500
Re: Tracking and Reporting Effective Type Shao Miller <sha0.miller@gmail.com> - 2013-01-14 01:03 -0500
Re: Tracking and Reporting Effective Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-15 00:28 -0500
Re: Tracking and Reporting Effective Type Shao Miller <sha0.miller@gmail.com> - 2013-01-15 05:39 -0500
Re: Tracking and Reporting Effective Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-17 00:32 -0500
Re: Tracking and Reporting Effective Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-17 01:23 -0500
Re: Tracking and Reporting Effective Type Shao Miller <sha0.miller@gmail.com> - 2013-01-17 22:47 -0500
Re: Tracking and Reporting Effective Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-18 16:14 -0500
Re: Tracking and Reporting Effective Type Wojtek Lerch <wojtek_l@yahoo.ca> - 2013-01-18 16:21 -0500
csiph-web