是否可以使用sizeof对void指针执行算术运算?

时间:2010-12-22 08:29:27

标签: c++ pointers

是否可以在不使用强制转换的情况下对void指针执行算术运算?

如果我有一个泛型函数,它接受一个未知类型的指针和一个指定类型大小的整数。是否有可能只用两个参数执行一些指针算术?

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

2 个答案:

答案 0 :(得分:4)

不,因为编译器不知道void指针指向的项的大小。您可以将指针强制转换为(char *)以执行上面所需的操作。

答案 1 :(得分:1)

  • 警告 - 以下内容可能会产生误导。正如评论中的其他人所指出的那样(特别感谢Steve Jessop),与基于强制转换的双关语相比,下面基于联合的类型双关语在标准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*以字节为单位添加偏移量。