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

pm1*_*100 14 c void-pointers

这是有效的

void *p = &X; /* some thing */
p += 12;
Run Code Online (Sandbox Code Playgroud)

如果是的话,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 ++都拒绝它

Jar*_*Par 16

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

如果你想按特定的字节数递增它,那么这就是我使用的解决方案.

p = ((char*)p) + 12;
Run Code Online (Sandbox Code Playgroud)

char类型是方便的,因为它有一个定义的1个字节的尺寸.

编辑

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

-Wall -ansi -pedantic
Run Code Online (Sandbox Code Playgroud)

  • Visual Studio默认将代码编译为C++,这就是它抛出错误的原因. (2认同)

dre*_*lax 12

引用规范:

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

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

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

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

因此,没有为指向void类型的指针定义指针算术.


rus*_*lik 5

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

编辑:这仅适用于void指针算法。在这种情况下,使用sizeof(int)或0的步长毫无意义。使用它的人的共同期望是最小的可能步长。

  • 也许是小的值1。 (23认同)
  • @Jason,谢谢您浪费我几分钟的时间,因为我坐在椅子上无助地大笑:) (4认同)