Topic: POD union and casting


Author: David R Tribble <david@tribble.com>
Date: 2000/06/28
Raw View
Joachim Fabini wrote:
> Is there any safe (i.e: portable) way to convert a pointer
> to a POD union U to a pointer to a POD struct A if that
> struct A is _not_ part of the union?
>
> Assume a library function that allocates and initializes memory
> required to fit a struct A and returns a value of type union U*
> _without_ knowing the definition of union U (user-defined !!).
> The prototype is declared in the library's header file:
>
> union U* allocate(size_t size);
>
> Bad style, of course. The documentation of allocate() says
> that the returned union U* points to an initialized struct A.

Off the top of my head, I would think that a pointer to struct A
would have to be the same as a pointer to the first member of
struct A, for example, an int.  In addition, a struct pointer must
point to data that is suitably aligned for the widest (most
restrictive) member type within the struct, regardless of the type
of the first member.

A pointer to a union has to be able to point to any of its members,
meaning that they are all aligned on the widest (most restrictive)
member type.

So, provided that union U contains a member that has anlignment
that is at least as wide as the alignment of the most restrictive
member of struct A, it would seem to me that a pointer to union U
can be converted into a pointer to struct A safely and portably.

It should also be obvious that if the allocate() function above
always allocates enough memory for struct A, and that memory is
suitably aligned for any type (e.g., such as by calling malloc()),
then the pointer it returns should be convertible to any struct A.

But I agree, this is not good style.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.com



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]







Author: James Kuyper <kuyper@wizard.net>
Date: 2000/06/29
Raw View
David R Tribble wrote:
....
> Off the top of my head, I would think that a pointer to struct A
> would have to be the same as a pointer to the first member of
> struct A, for example, an int.  In addition, a struct pointer must

That's guaranteed only for POD-structs. See section 9.2p17.

....
> A pointer to a union has to be able to point to any of its members,
> meaning that they are all aligned on the widest (most restrictive)
> member type.

Section 9.5p1 says that "Each data member of a union is allocated as if
it were the sole member of a struct". Therefore, every data member that
would allow the struct to be a POD struct must be allocated at the same
place as the start of the union.

However, that argument doesn't apply to data members that would make a
struct a non-POD struct. That would include any members which are
private, protected, of type pointer-to-member, non-POD struct, or
non-POD union, or array of same, or reference. In principle, such data
members can be allocated somewhere other than the start of the union. I
don't think this was intentional, and I doubt that any real
implementation takes advantage of that freedom.



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]







Author: Joachim Fabini <Joachim.Fabini@gmx.net>
Date: 2000/06/20
Raw View
Is there any safe (i.e: portable) way to convert a pointer
to a POD union U to a pointer to a POD struct A if that
struct A is _not_ part of the union?

Assume a library function that allocates and initializes memory
required to fit a struct A and returns a value of type union U*
_without_ knowing the definition of union U (user-defined !!).
The prototype is declared in the library's header file:

union U* allocate(size_t size);

Bad style, of course. The documentation of allocate() says
that the returned union U* points to an initialized struct A.
I suspect this to be non-portable, as imho the only way how
to achieve portable layout-equivalence between two POD unions
is (according to C++ standard, 9.2.15) the same number of
members and layout-compatible types within the union
definitions. The library imho can never guarantee this, as it
is the user's responsability to define union U.

If the library internally uses the definition
   union U {struct A a;};
and the user defines
   union U {struct A a; struct B b;};
the two resulting unions need not be layout-compatible
according to the standard. Or do I miss something and it is safe
and standard-conforming to do one or both of the following:

union U {struct A a; struct B b;}
union V {struct A a;}
union U* u = allocate(n);
union V* v = reinterpret_cast<union V*>(u);
v->a.xxx = yyyy;

To come back to my initial question: What about this sequence
that imho is also _not_ standard-compliant:

union U {struct B b;};  // U does NOT include struct A !!!!
union V {struct A a; struct B b;};
union U* u = allocate(n);
union V* v = reinterpret_cast<union V*>(u);
v->a.xxx = yyyy;

Thanks in advance for your comments!
Best regards
--Joachim Fabini

PS: Given the constraints specified by 9.2.16 and 9.2.17, the
layout chosen by most compiler vendors for POD unions is
most likely similar to the one used for POD structs, so in most
situations even a reinterpret_cast<struct A*>(u) has
major chances to succeed. Unfortunately it's not portable.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]