I\'m reading paragraph 7 of 6.5 in ISO/IEC 9899:TC2.
It condones lvalue access to an object through:
an aggregate or union type that includes
The answer to this question is covered in proposal: Fixing the rules for type-based aliasing which we will see, unfortunately was not resolved in 2010 when the proposal was made which is covered in Hedquist, Bativa, November 2010 minutes . Therefore C11 does not contain a resolution to N1520
, so this is an open issue:
There does not seem to be any way that this matter will be resolved at this meeting. Each thread of proposed approaches leads to more questions. 1 1:48 am, Thurs, Nov 4, 2010.
ACTION – Clark do more work in
N1520
opens saying (emphasis mine going forward):
Richard Hansen pointed out a problem in the type-based aliasing rules, as follows:
My question concerns the phrasing of bullet 5 of 6.5p7 (aliasing as it applies to unions/aggregates). Unless my understanding of effective type is incorrect, it seems like the union/aggregate condition should apply to the effective type, not the lvalue type.
Here are some more details:
Take the following code snippet as an example:
union {int a; double b;} u; u.a = 5;
From my understanding of the definition of effective type (6.5p6), the effective type of the object at location &u is union {int a; double b;}. The type of the lvalue expression that is accessing the object at &u (in the second line) is int.
From my understanding of the definition of compatible type (6.2.7), int is not compatible with union {int a; double b;}, so bullets 1 and 2 of 6.5p7 do not apply. int is not the signed or unsigned type of the union type, so bullets 3 and 4 do not apply. int is not a character type, so bullet 6 does not apply.
That leaves bullet 5. However, int is not an aggregate or union type, so that bullet also does not apply. That means that the above code violates the aliasing rule, which it obviously should not.
I believe that bullet 5 should be rephrased to indicate that if the effective type (not the lvalue type) is an aggregate or union type that contains a member with type compatible with the lvalue type, then the object may be accessed.
Effectively, what he points out is that the rules are asymmetrical with respect to struct/union membership. I have been aware of this situation, and considered it a (non-urgent) problem, for quite some time. A series of examples will better illustrate the problem. (These examples were originally presented at the Santa Cruz meeting.)
In my experience with questions about whether aliasing is valid based on type constraints, the question is invariably phrased in terms of loop invariance. Such examples bring the problem into extremely sharp focus.
And the relevant example that applies to this situation would be 3
which is as follows:
struct S { int a, b; }; void f3(int *pi, struct S *ps1, struct S const *ps2) { for (*pi = 0; *pi < 10; ++*pi) { *ps1++ = *ps2; } }
The question here is whether the object *ps2 may be accessed (and especially modified) by assigning to the lvalue *pi — and if so, whether the standard actually says so. It could be argued that this is not covered by the fifth bullet of 6.5p7, since *pi does not have aggregate type at all.
Perhaps the intention is that the question should be turned around: is it allowed to access the value of the object *pi by the lvalue *ps2. Obviously, this case would be covered by the fifth bullet.
All I can say about this interpretation is that it never occurred to me as a possibility until the Santa Cruz meeting, even though I've thought about these rules in considerable depth over the course of many years. Even if this case might be considered to be covered by the existing wording, I'd suggest that it might be worth looking for a less opaque formulation.
The following discussion and proposed solutions are very long and hard to summarize but seems to end with a removal of the aforementioned bullet five and resolve the issue with adjustments to other parts of 6.5
. But as noted above this issues involved were not resolvable and I don't see a follow-up proposal.
So it would seem as it standard the wording does seem to permit the scenario the OP demonstrates although my understanding is that this was unintentional and therefore I would avoid it and it could potentially change in later standards to be non-conforming.