【问题标题】:Should the compiler warn on pointer arithmetic with a void pointer?编译器是否应该使用 void 指针警告指针算术?
【发布时间】:2014-01-07 09:21:19
【问题描述】:

我正在使用 gcc 4.7.2 编译 C 程序。我有一个带有一些偏移量的 void * 类型的地址。 (void* + size) 应该给出警告。如果不是,那么如果 size 为 1 且 size 为 50,它将添加多少字节。 我唯一关心的应该是警告我们正在向 void 指针添加一些东西?

 12         int size = 50;
 /*Allocate a block of memory*/
 14         void *BlockAddress   = malloc(200);
 15         if(!BlockAddress)
 16                  return -1;
 17         address1             = (int *)BlockAddress;
 18         address2             = BlockAddress + 1*size;
 19         address3             = BlockAddress + 2*size;

谢谢

【问题讨论】:

  • 你可以检查一下,但我认为如果它有效,它会增加 4 个字节(指针大小)。除非您指定类型,否则编译器无法知道要添加多少字节。例如。对于 char 添加 1 个字节,对于 int 指针添加 4 个字节,依此类推。所以,我认为默认值将是 4 字节的指针大小。
  • 是的,我已经检查过了。除非我编译并运行它,否则我的想法与您的想法相同,该程序编译时没有错误或警告。它是加 1 而不是 4,这就是为什么要问为什么会这样。?

标签: c pointers


【解决方案1】:

您不应该对 void 指针进行指针运算。

来自 C 标准

6.5.6-2:对于加法,两个操作数都应具有算术类型,或者一个操作数应是指向对象类型的指针,而另一个应具有整数类型。

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

考虑到void 的大小是1,GNU C 允许上述情况。

来自6.23 Arithmetic on void- and Function-Pointers

在 GNU C 中,指向 void 的指针和指向函数的指针支持加法和减法运算。这是通过将 void 或函数的大小视为 1 来完成的。

所以通过以上几行我们得到:

 address2             = BlockAddress + 1*size; //increase by 50 Bytes
 address3             = BlockAddress + 2*size; //increase by 100 Bytes

【讨论】:

  • gcc 对此表示 warning: pointer of type 'void *' used in arithmetic
  • 感谢 Acme,至少这有点道理,因为您说“GNU C 通过考虑 void 的大小为 1 来允许上述内容”现在 void 的大小听起来很可怕吗?不是吗?
  • @Javed - 是的,这就是我所相信的答案。
  • @Javed - 他们一定有这样做的理由 - 因为他们还提供了许多其他功能作为扩展。 C 是一种你永远不会停止学习 C 的语言。
  • 你是绝对正确的。你的回答真的很有帮助。谢谢
【解决方案2】:

void * 的指针运算是 GCC extension,而不是标准 C。

最好不要做这样的事情。使用char * BlockAddress = malloc(200); 或将其转换为address2address3

【讨论】:

  • 他们为什么会想出这样一个盲目的扩展?这太疯狂了。
  • 谢谢,我知道我有类型转换才能正确操作,假设我碰巧忘记了类型转换,所以它应该给我警告或更正确的应该给我一个错误?
  • 这取决于您给出的警告级别和选项。
  • @Rob 我觉得它很有用,但由于它是 GCC 扩展,最好不要使用它。
  • @Javed 那么它应该会警告你。
【解决方案3】:

这是完全有效的。 void* 包含一个地址,添加一个只是指向内存中的下一个字节。这里没什么好担心的......

【讨论】:

  • 谢谢 It'sPate,但你不认为如果采用 int ptr 那么它将增加 4 个字节并增加 8 个字节,而 char 指针只有 1 个字节,那么 void 的定义是什么?那是1。这就是为什么不,因为它进入下一个位置..
猜你喜欢
  • 2015-01-01
  • 1970-01-01
  • 2017-07-12
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
  • 2016-09-25
  • 2021-04-29
相关资源
最近更新 更多