如何确定 C99 中所需的最大对齐

How to determine maximum required alignment in C99

是否有一种仅依赖于 C99 标准提供的可移植方法来找出任何数据类型所需的最大对齐要求。

类似于 C++11 中的 maxalign_t

我目前正在做的是计算 intlong intlong long int、[=15= 对齐的最小公倍数 (lcm) ]、void *size_t 作为确定对齐的最大努力方式。

更新: 我目前需要这个来实现围绕 malloc 的包装器,它在内存块的开头存储元数据,returns 一个地址比 malloc 返回的地址更高的指针。

确实没有一个好的方法来做到这一点,这就是 maxalign_t 由 C11 引入的原因。虽然,我无法想象一个普通系统存在比 intmax_t 更高对齐要求的类型,因此您不妨使用它并在 maxalign_t 不可用时为 99% 的系统获得正确答案。

您可以通过分配几个块并查看每个块是否在 16、8 或 4 字节边界上对齐来凭经验确定支持的最大对齐。

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;
}

调用 GetMaxSupportedAlignment() 将 return 在 64 位操作系统上为 8 个,在许多 32 位系统上为 4 个。