Reputation: 2490
Is there a portable way that only relies on what the C99 standard provides to find out the maximum required alignment that is needed for any data type.
Like maxalign_t
in C++11.
What I'm currently doing is calculating the least common multiple (lcm
) of the alignments of int
, long int
, long long int
, double
, void *
and size_t
as best effort way of determining the alignment.
Update:
I currently need this for implementing a wrapper around malloc
that stores metadata at the beginning of the block of memory and returns a pointer with a higher address than what malloc
has returned.
Upvotes: 8
Views: 2028
Reputation: 550
You can determine the maximum supported alignment empirically by allocating several chunks and seeing if each chunk is aligned on a 16, 8, or 4 byte boundary.
bool GetConsistentAlignment( std::size_t alignment )
{
const unsigned int chunkCount = 16;
void * places[ chunkCount ];
memset( places, 0, sizeof(places) );
bool consistent = true;
for ( unsigned int ii = 0; ii < chunkCount; ++ii )
{
const std::size_t size = 1024 + rand() % 4096;
void * chunk = malloc( size );
places[ ii ] = chunk;
}
for ( unsigned int ii = 0; ii < chunkCount; ++ii )
{
void * chunk = places[ ii ];
const std::size_t place = reinterpret_cast< const std::size_t >( chunk );
if ( place % alignment != 0 )
{
consistent = false;
}
free( chunk );
}
return consistent;
}
std::size_t GetMaxSupportedAlignment()
{
static std::size_t maxAlignment = 0;
if ( maxAlignment == 0 )
{
std::srand( std::time( 0 ) );
std::size_t alignment = 64;
while ( alignment > 1 )
{
const bool isConsistentAlignment = GetConsistentAlignment( alignment );
if ( isConsistentAlignment )
{
break;
}
alignment /= 2;
}
maxAlignment = alignment;
}
return maxAlignment;
}
Calling GetMaxSupportedAlignment()
will return 8 on 64-bit operating systems and 4 on many 32-bit systems.
Upvotes: 1
Reputation: 93082
There isn't really a good way to do that, which is why maxalign_t
was introduced by C11. Though, I cannot imagine an ordinary system where a type with higher alignment requirements than intmax_t
exists so you might as well use that and get the right answer for 99% of the systems when maxalign_t
is not available.
Upvotes: 3