uintptr_t портативная альтернатива - PullRequest
9 голосов
/ 16 февраля 2011

Я хочу выполнить проверку выравнивания памяти какого-либо типа 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);
}

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

Спасибо.

1 Ответ

1 голос
/ 17 февраля 2011

Я не уверен, что вопрос здесь."Как вы думаете?"Я думаю, что ptrdiff_t действительно является правильным типом данных для представления различий между двумя указателями, но не имеет смысла сравнивать два указателя, если они не указывают на блок непрерывной памяти, который получается из простого выделения (и, как следствие, нииз двух сравниваемых указателей всегда должно быть NULL).

...