Учитывая указатель на T, я хотел бы определить, не перекрывает ли T адрес, выровненный по N байтам. На практике меня волнует только то, имеют ли объекты размером 0-5 байт границы 8 или 16 байтов, но я написал эту общую версию:
template<class T, unsigned long N>
bool straddlesBoundary(T* obj)
{
unsigned long before = (unsigned long)obj & ~(N-1);
unsigned long after = ((unsigned long)obj + sizeof(T) - 1) & ~(N-1);
return before != after;
}
По сути, округляем адрес до ближайшего N-байтового выровненного адреса, затем возьмем приращение указателя на величину T минус один (потому что T, заканчивающийся прямо на следующей границе, не считается стреловым) и округлим его до ближайшего Выровненный по байту адрес, и если они совпадают, вы знаете, что это не колеблется.
Есть ли более быстрый способ сделать это? Я только что сделал это, я не знаю, есть ли стандартная проверка.
Изменить: Обратите внимание, я предполагаю, что T меньше, чем N.
Вы могли бы сделать:
unsigned long offset = (unsigned long)obj & (N-1);
return offset > N - sizeof(T);
(этот код, как и ваш, работает, только если N является степенью 2.)
Других решений пока нет …