Re: Alignment
On Feb 26, 7:57 pm, peter koch <peter.koch.lar...@gmail.com> wrote:
On 26 Feb., 19:36, better_cs_...@yahoo.com wrote:
[...]
To force the unsigned char array to have the same alignment
as the Foo (which is my goal), I'd like to put these
together in a union. However, Foo has a non-trivial
constructor, so it may not be a member of a union. Do I have
any othre options?
Yes. Search this group and the moderated one for a solution
that will give the correct alignment (basically: a union
containing all possible types and the char representation).
I'm pretty sure you know this, but for precision's sake: the set
of all possible types is infinite, which means that you're going
to have to compromize some. Generally speaking, the set of all
basic types, plus a couple of different types of pointers
(void*, int*, struct X*, a pointer to a function, maybe pointers
to different types of members) should largely suffice. (It
would fail, of course, if in the implementation, the size of a
pointer depends on a hash code of the canonical type of the
pointed to object. Which is, I think, legal, but not something
I'd worry about encountering. It might change if the compiler
ensures some sort of special alignment for arrays, in order to
use some special hardware.)
In practice, this may result in a larger array than necessary if
the other type is small, e.g.:
struct Foo { char a[2] ; } ;
union {
unsigned char data[ sizeof( Foo ) ] ;
MaxAlignment dummyForAlignment ;
} ;
(where MaxAlignment is a union of all of the types). To avoid
this, you can do something like:
template< typename T, bool isSmaller >
struct AlignTypeDetail ;
template< typename T >
struct AlignTypeDetail< T, false >
{
typedef T type ;
} ;
template< typename T >
struct AlignTypeDetail< T, true >
{
typedef char type ;
} ;
template< typename T, typename U >
struct AlignType
{
typedef typename AlignTypeDetail< U, (sizeof( T ) < sizeof
( U )) >::type
type ;
} ;
template< typename T >
union MaxAlignFor
{
typename AlignType< T, char >::type c ;
typename AlignType< T, short >::type s ;
typename AlignType< T, int >::type i ;
typename AlignType< T, long >::type l ;
typename AlignType< T, long long >::type ll ;
typename AlignType< T, float >::type f ;
typename AlignType< T, double >::type d ;
typename AlignType< T, long double >::type ld ;
typename AlignType< T, void* >::type pc ;
typename AlignType< T, MaxAlign* >::type ps ;
typename AlignType< T, void (*)() >::type pf ;
// (I've yet to find a machine where I've needed
// more than the above.)
} ;
Since the required alignment for Foo can never be more than
sizeof(Foo), this only puts types whose size is less than or
equal to the size of Foo in the union.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34