Topic: Aliasing objects of unrelated layout-compatible types
Author: Pavel Minaev<int19h@gmail.com>
Date: Thu, 14 Apr 2011 13:11:07 CST Raw View
(all references to the standard below are to C++0x FDIS / N3290)
Consider this code:
struct S1 { int x; };
struct S2 { int y; };
int main() {
S1 s1 = {0};
S2* s2 = (S2*)&s1;
++s2->y;
}
S1 and S2 here are layout-compatible types. Consequently, so far as I
can see, the storage allocated for s1 is also suitable for *s2; and
lifetime of either starts from the moment storage of suitable size&
alignment is allocated.
So, then, is it correct to say that the only reason why the above is
UB is because of 3.10/10, "If a program attempts to access the stored
value of an object through a glvalue of other than one of the
following types the behavior is undefined"?
Assuming that it is, the list in 3.10/10 includes one interesting
exception:
"an aggregate or union type that includes one of the aforementioned
types among its elements or nonstatic data members"
So suppose then I write instead:
union U { S1 s1; S2 s2; };
int main() {
S1 s1 = {0};
U* u = (U*)s1;
S2* s2 =&u->s2;
++s2->y;
}
Would that be legal? According to 9.5/1, "it is permitted to inspect
the common initial sequence of any of standard-layout struct members".
In this case, the common initial sequence is the entirety of S1 and
S2. So it would seem that it is legal for me to inspect U::s2, and the
use of union works around the strict aliasing rule?
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Joshua Maurice<joshuamaurice@gmail.com>
Date: Tue, 19 Apr 2011 13:07:57 CST Raw View
On Apr 14, 12:11 pm, Pavel Minaev<int...@gmail.com> wrote:
> (all references to the standard below are to C++0x FDIS / N3290)
>
> Consider this code:
>
> struct S1 { int x; };
> struct S2 { int y; };
>
> int main() {
> S1 s1 = {0};
> S2* s2 = (S2*)&s1;
> ++s2->y;
> }
>
> S1 and S2 here are layout-compatible types. Consequently, so far as I
> can see, the storage allocated for s1 is also suitable for *s2; and
> lifetime of either starts from the moment storage of suitable size&
> alignment is allocated.
>
> So, then, is it correct to say that the only reason why the above is
> UB is because of 3.10/10, "If a program attempts to access the stored
> value of an object through a glvalue of other than one of the
> following types the behavior is undefined"?
>
> Assuming that it is, the list in 3.10/10 includes one interesting
> exception:
>
> "an aggregate or union type that includes one of the aforementioned
> types among its elements or nonstatic data members"
>
> So suppose then I write instead:
>
> union U { S1 s1; S2 s2; };
> int main() {
> S1 s1 = {0};
> U* u = (U*)s1;
> S2* s2 =&u->s2;
> ++s2->y;
> }
>
> Would that be legal? According to 9.5/1, "it is permitted to inspect
> the common initial sequence of any of standard-layout struct members".
> In this case, the common initial sequence is the entirety of S1 and
> S2. So it would seem that it is legal for me to inspect U::s2, and the
> use of union works around the strict aliasing rule?
I'm sorry you've obtained no replies. I've had a thread up here for
months now asking similar questions, also without reply. I am slightly
concerned that no one else is concerned about this, and the arguable
defects in the last C++0x draft which I've read.
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]