Daniel said:
Hello:
Does anyone know what the size of this class?
class T {
char a;
double b;
char c;
class T *p
};
thank you
-Daniel
This should give you an idea. I don't know of any implementation that
does not use the algorithm depicted by ComputeAlignment().
You'll need to know the "packing" of the struct (#pragma pack) which is
the 2 raised to the i_max_align parameter.
#include <algorithm>
#include <iostream>
struct SizeAlignment
{
int m_size;
int m_alignment; /** alignment is a power of 2 */
SizeAlignment( int i_size = 1, int i_alignment = 0 )
: m_size( i_size ),
m_alignment( i_alignment )
{
}
};
struct Offset
{
int m_offset;
SizeAlignment m_size_alignment;
Offset( const SizeAlignment & i_size_alignment )
: m_size_alignment( i_size_alignment )
{
}
};
int Align( int i_pos, int i_alignment )
{
int i_mask = 1 << i_alignment;
return 1 + ( ( i_pos - 1 ) | ( i_mask - 1 ) );
}
template <typename T>
SizeAlignment ComputeAlignment(
const T & i_begin,
const T & i_end,
int i_max_align = 2 // pack value
) {
Offset l_sa( SizeAlignment( 0, 0 ) );
T l_iter = i_begin;
while ( l_iter != i_end )
{
int l_new_alignment =
std::min( i_max_align, l_iter->m_size_alignment.m_alignment );
l_iter->m_offset =
Align( l_sa.m_size_alignment.m_size, l_new_alignment );
l_sa.m_size_alignment.m_alignment =
std::max( l_sa.m_size_alignment.m_alignment, l_new_alignment );
l_sa.m_size_alignment.m_size =
l_iter->m_offset + l_iter->m_size_alignment.m_size;
++ l_iter;
}
l_sa.m_size_alignment.m_size =
Align( l_sa.m_size_alignment.m_size,
l_sa.m_size_alignment.m_alignment );
return l_sa.m_size_alignment;
}
// These defs are system dependant - define these for all
// the system types for each platform. Some platforms will
// have ways of determining the alignments.
SizeAlignment g_Align_char( sizeof( char ), 0 );
SizeAlignment g_Align_short( sizeof( short ), 1 );
SizeAlignment g_Align_int( sizeof( int ), 2 );
template <typename T, int N >
T * End( T (& i_array )[ N ] )
{
return N + i_array;
}
template <typename T, int N >
int Nelem( T (& i_array )[ N ] )
{
return N;
}
void test()
{
// Create a struct with a char, a short and three following chars
//
Offset l_struct[] = {
Offset( g_Align_char ),
Offset( g_Align_short ),
Offset( g_Align_char ),
Offset( g_Align_char ),
Offset( g_Align_char ),
};
// compute the alignment with a maximum packing 4 (2^2).
SizeAlignment l_sa =
ComputeAlignment( & l_struct[0], End( l_struct ), 2 );
// print out the results.
for ( int i = 0; i < Nelem( l_struct ); ++ i )
{
std::cout
<< "Offset element "
<< i
<< " "
<< l_struct[ i ].m_offset << "\n";
}
std::cout
<< "Struct size "
<< l_sa.m_size
<< " alignment "
<< l_sa.m_alignment << "\n";
}
int main()
{
test();
}