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 Newsgroups: comp.std.c Subject: Re: Tracking and Reporting Effective Type Date: Tue, 15 Jan 2013 00:28:03 -0500 Lines: 149 Message-ID: References: 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: Xref: csiph.com comp.std.c:1836 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.