переносимая альтернатива uintptr_t

Я хочу выполнить проверку выравнивания памяти некоторого типа T . Самый простой способ сделать это -

if (((uintptr_t)&var & __alignof(T) - 1) == 0) ...

, однако uintptr_t не является частью существующего стандарта C ++ и не поддерживается некоторыми компиляторами, поэтому я ' Я ищу переносимый альтернативный способ сделать это, и std :: ptrdiff_t мне подходит. std :: ptrdiff_t гарантированно сможет хранить разницу между двумя указателями, но кто сказал, что один из этих указателей не может быть нулевым указателем? В этом случае std :: ptrdiff_t должен быть как минимум того же размера, что и сам указатель.

template <typename T> bool is_properly_aligned(const T* const ptr)
{
    std::ptrdiff_t diff = (ptr - static_cast<T*>(0)) * sizeof(T);
    return ((diff & __alignof(T) - 1) == 0);
}

или тому подобное (чтобы избавиться от умножения на sizeof (T) )

template <typename T> bool is_properly_aligned(const T* const ptr)
{
    std::ptrdiff_t diff =
        reinterpret_cast<const char*>(ptr) - static_cast<const char*>(0);
    return ((diff & __alignof(T) - 1) == 0);
}

Что вы думаете о таком решении? Достаточно ли он портативен? Я не вижу причин, по которым это должно не получиться, однако я хотел бы подтвердить.

Спасибо.

9
задан ledokol 16 February 2011 в 05:47
поделиться