Можно ли выполнить арифметическую операцию с указателем void с sizeof?

Возможно ли выполнить арифметическую операцию по указателю void без использования кастинга?

Если у меня есть общая функция, которая принимает указатель неизвестного типа и целое число, определяющее размер этого типа. Возможно ли выполнить некоторую арифметику указателя только с двумя аргументами?

void* Function( void* ptr, int size); 

  • Предупреждение – ниже, вероятно, вводит в заблуждение. Как отмечают другие в комментариях (особая благодарность Стиву Джессопу), на основе профсоюза типа pun ниже нет особых гарантий в стандартном C ++ по сравнению с кастомизированными каламбурами, а использование casts для char* для выполнения арифметики указателя, вероятно, будет более переносимым что использование союзов для преобразования в целые числа.

Для этого вам нужна какая-то форма типа punning из-за массивной семантики указателей в стандартном 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* для добавления смещения в байтах.

Нет, потому что компилятор не знает размер элемента (ов), на который указывает указатель на пустоту. Вы можете направить указатель на (char *), чтобы сделать то, что вы хотите выше.