Previously, in basic.lval, there was this bullet point:
an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
In the current draft, it is gone.
There is some background information at WG21's site: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1359r0.html#2051:
The aliasing rules of 7.2.1 [basic.lval] paragraph 10 were adapted from C with additions for C++. However, a number of the points either do not apply or are subsumed by other points. For example, the provision for aggregate and union types is needed in C for struct assignment, which in C++ is done via constructors and assignment operators in C++, not by accessing the complete object.
Can anyone explain to me, what this means? What has this strict aliasing rule to do with struct assignment in C?
cppreference says about this rule:
These bullets describe situations that cannot arise in C++
I don't understand, why it is true. For example,
struct Foo {
float x;
};
float y;
float z = reinterpret_cast<Foo*>(&y)->x;
The last line seems to do what the bullet point describes. It accesses y
(a float
) through an aggregate, which includes a float
(member x
).
Can anyone shed some light on this?
struct S { int a; float b; };
andfloat *c = malloc(100);
and int and float are the same size and no padding; thenc[0] = c[1] = 0; S s = *(S *)c;
is not an aliasing violation according to that text, because thefloat
c[0]
is accessed by an aggregate type that has afloat
as its member (never mind the fact that the offset of the member doesn't correspond to the memory being accessed) – ActinomycetemyUnion.member1
would be an access tomyUnion
, which would be a struct union which containsmyUnion.member2
, and thus such an access would be allowed to modify the stored value of the latter. – Ocasio