- Предупреждение - приведенное ниже, вероятно, вводит в заблуждение. Как указано другими в комментариях (особая благодарность Стиву Джессопу), приведенный ниже объединенный тип каламбура не имеет особых гарантий в стандартном C ++ по сравнению с каламбурами на основе приведения, и использование приведений к
char*
для выполнения арифметики с указателями, вероятно, будет более переносимый, который использует союзы для преобразования в целые числа.
Для этого вам нужна некоторая форма штамповки типов из-за массивоподобной семантики указателей в стандарте C ++. Я буду обманывать, используя каламбур на основе профсоюзов ...
inline void* Ptr_Add (void* p1, std::ptrdiff_t p2)
{
union
{
void* m_Void_Ptr;
std::ptrdiff_t m_Int;
} l_Pun;
l_Pun.m_Void_Ptr = p1;
l_Pun.m_Int += p2;
return l_Pun.m_Void_Ptr;
}
У меня есть этот точный код в моей библиотеке, наряду с некоторыми другими для выполнения арифметических и побитовых операций с байтовыми указателями. Существуют каламбуры на основе объединения, потому что каламбуры на основе приведения могут быть хрупкими (анализ псевдонима указателя в оптимизаторе может не определить псевдоним, поэтому полученный код ведет себя неправильно).
Если вы используете offsetof
, IMO вам понадобится набор функций, подобных этому. Они не совсем хороши, но они намного приятнее, чем делать все проколы везде, где нужно применить смещение к указателю.
Как подсказывает ruslik, в GCC есть расширение, которое (если вы не возражаете против непереносимого кода) рассматривает размер void
как 1, так что вы можете использовать +
на void*
для добавить смещение в байтах.