14

这是有效的吗

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

如果是的话 p 现在指向什么?我有(第三方)代码可以做到这一点(并且可以干净地编译),我的猜测是 void * 被视为 char *。我信任的 K&R 对这个话题保持沉默(ish)

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

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

顺便说一句 gcc -pedantic 抛出警告

概括:

C规范是模棱两可的。它表示在表示和用作函数参数方面 void* =char*。但它对指针算术保持沉默。

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

6 回答 6

17

不,这是不合法的。Avoid*不能任意递增。它需要首先转换为特定类型。

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

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

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

编辑

有趣的是,它在 gcc 上运行并带有警告。我在 Visual Studio 2010 上测试并验证它无法编译。我对标准的有限理解会说 gcc 在这里出现错误。您可以添加以下编译标志吗

-Wall -ansi -pedantic
于 2010-10-25T23:30:16.293 回答
12

引用规范:

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

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

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

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

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

于 2010-10-26T00:24:07.907 回答
5

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

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

于 2010-10-25T23:31:52.987 回答
2

你的猜测是正确的。

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

于 2010-10-25T23:59:55.757 回答
2

您可能想看看这个问题的最高投票答案

C中void指针的指针算法

于 2014-02-17T06:30:31.483 回答
1

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

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

于 2010-10-25T23:45:58.937 回答