我可以对C中的void *指针进行算术运算吗?

时间:2010-10-25 23:25:11

标签: c void-pointers

是有效的

void *p = &X; /* some thing */
p += 12;

如果是的话,p现在指向什么? 我有(第三方)代码执行此操作(并编译干净)我的猜测是void *被视为char *。我信赖的K& R对这个主题保持沉默(ish)

编辑:我的小测试应用程序在gcc 4.1.1上运行正常,并将void *视为char *。但是g ++ barfs

我知道如何正确地做到这一点。我需要知道是否必须清理此代码库以找到它完成的所有位置。

BTW gcc -pedantic会发出警告

要点:

C规范含糊不清。它表示在表示和用作函数参数方面void * = char *。但它对指针算法没有提及。

  • gcc(4)允许并将其视为 char *
  • g ++拒绝它
  • gcc -pedantic警告它
  • vs2010 c和c ++ 拒绝它

6 个答案:

答案 0 :(得分:15)

不,这不合法。 void*不能随意增加。首先需要将其强制转换为特定类型。

如果要将其增加特定的字节数,那么这就是我使用的解决方案。

p = ((char*)p) + 12;

char类型很方便,因为它的定义大小为1个字节。

编辑

有趣的是它在gcc上运行并发出警告。我在Visual Studio 2010上测试并验证它不能编译。我对标准的理解有限,会说gcc出现错误。你可以添加以下编译标志

-Wall -ansi -pedantic

答案 1 :(得分:12)

引用规范:

  

§6.5.6/ 2 :另外,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针,另一个操作数应具有整数类型。 (递增相当于添加1.)

指向void的指针不是指向对象类型的指针,根据以下摘录:

  

§6.2.5/ 1 :[...]类型   被分为对象类型(完全描述对象的类型),函数类型(类型   描述函数)和不完整类型(描述对象但缺乏的类型)   确定其大小所需的信息。)

     

§6.2.5/ 19 :void类型包含一组空值;它是一种不完整的类型   完成。

因此,对于指向void类型的指针,指针算法未定义

答案 2 :(得分:4)

这取决于编译器。那些允许它将sizeof(*(void *))视为1。

编辑:它仅用于无效指针算术。在这种情况下使用sizeof(int)或0的步骤是没有意义的。使用它的人的共同期望是可能的最小步骤。

答案 3 :(得分:2)

你的猜测是正确的。

在标准ISO C99第6.2.5节第26段中,它声明void指针和字符指针将具有相同的表示和对齐要求(释义)。

答案 4 :(得分:2)

您可能希望查看此问题的最高投票答案

Pointer arithmetic for void pointer in C

答案 5 :(得分:1)

我认为你不能,因为它不知道它的类型,因此无法寻找正确的字节数。

首先将其转换为类型,即(int)