为啥后缀增量不适用于 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?