为啥后缀增量不适用于 void *ptr,但 ptr = ptr + 1 有效?

Posted

技术标签:

【中文标题】为啥后缀增量不适用于 void *ptr,但 ptr = ptr + 1 有效?【英文标题】:Why does postfix increment not work on a void *ptr, but ptr = ptr + 1 works?为什么后缀增量不适用于 void *ptr,但 ptr = ptr + 1 有效? 【发布时间】:2015-07-19 17:13:57 【问题描述】:

如果我这样做:

int x = 10;
void *ptr = &x;
ptr++;

"ptr++" 行出错。

但是,如果我这样做而不是“ptr++”:

ptr = ptr + 1;

它工作得很好。可能是什么原因?

【问题讨论】:

Can't reproduce. C 没有在 void 指针上定义指针运算。因此,您可能会看到编译器扩展或错误。那你用的是什么编译器? @rakeb.void 我的只是一个不同的编译器。 @dlask gnu 编译器。我在 unix 平台上使用代码块。 【参考方案1】:

空指针算法在标准 C 中是非法的,但通常被 gcc 扩展允许。

从概念上讲,这是因为当您对指针执行增量时,它实际上会在后台执行缩放以添加适当数量的字节(由指针的类型给出)以使您进入下一个数据单元。

由于 void 指针可以指向任何类型,它可以避免您以不同于预期的方式访问部分内存。编译器不可能确定如何缩放加法,因为它不知道指向的类型。

在标准 C 中,ptr = ptr + 1 出于同样的原因也是非法的。您看到一项工作的原因是 gcc 扩展存在相同的问题。

当使用-pedantic-errors 标志时,两者都会在gcc 中出现错误。

【讨论】:

所以你的意思是说两者都应该根据C标准给出错误?第二个工作是因为不同的编译器? 是的,很多机器都有很多不同的 gcc 扩展,这些扩展可能允许某些事情,但不允许其他事情。但是,您可以根据 C 标准使用-pedantic-errors 标志来报告错误。 在理想情况下,这两种方法都行,或者都不行,因为无论如何它们在本机代码中都是一样的。但是唉……【参考方案2】:

C 标准禁止在 void* 上进行指针运算。虽然取决于编译器。 原因很简单,C 不是汇编 :-)

【讨论】:

以上是关于为啥后缀增量不适用于 void *ptr,但 ptr = ptr + 1 有效?的主要内容,如果未能解决你的问题,请参考以下文章

我对所有值求和,但为啥它不适用于所有动态总计字段

为啥 jQuery 选择器适用于 Chrome,但不适用于 Safari?

我的突变适用于 Amplify,但不适用于 Apollo。为啥?

GET 请求适用于 Postman,但为啥它不适用于 ReactJS fetch?

Ajax 加载面板适用于 FF,但不适用于 Chrome。知道为啥吗?

为啥空声明适用于带有 int 参数的定义,但不适用于 float 参数?