void *p = malloc(sizeof(B)); // 1
B* pb = (B*)p; // 2
pb->i = 0; // 3
short* ps = (short*)p; // 4
*ps = 0; // 5free(p); // 6
I assume that the reasoning would be that:
Again ignoring whether this is desirable, is that (roughly) the intent of the current wording?
If yes, does the wording express it (a) accurately and (b) clearly?
Finally, regardless of the above answer, do we want to change anything about the legality or semantics of the above type-punning code, such as possibly having a "type-safe mode" where such code is somehow not allowed unless in an "extern "C-compat"" block or something?
Herb
Richard, it cannot mean that (or if it does, IMO we have an obvious bug) for at least two specific reasons I can think of (below), besides the general reasons that it would not be sensical and would violate type safety.
First, objects must have unique addresses. Consider, still assuming B is trivially constructible:
void *p = malloc(sizeof(B));
B* pb = (B*)p;
pb->i = 0;
short* ps = (short*)p;
*ps = 0;This cannot possibly be construed as starting the lifetime of a B object and a short object, else they would have the same address, which is illegal. Am I missing something?
void *p = malloc(sizeof(B));
B* pb = (B*)p;
short* ps = (short*)p;
pb->i = 0;
*ps = 0;
As Matt alluded to in http://www.open-std.org/pipermail/ub/2014-January/000456.html, it might be possible to say that all lifetime effects are called out in explicit expressions without breaking C compatibility, *if* we instead say that accessing the members of objects with trivial constructors can be done outside of the lifetime of such objects. I have no idea whether that would be better or worse than saying that lifetime effects can be implied.
Jeffrey