[英]Why can I not do arithmetic on a cast of a void pointer?
void foo(void *ptr, int numBytes)
{
(char*)ptr += numBytes;
}
这不能在C中编译。我知道替代方案。 但为什么这不起作用? 问题是什么?
问题
问题是(char*)ptr
不会产生左值 ,这意味着该值无法修改 - 可以将其视为转换的临时结果,转换将产生类型为char*
的右值 。
它在语义上与您拥有以下示例相同,转换产生临时值,这样的值不能分配新值。
int x = 123;
(float)x += 0.12f; /* (1), illegal */
/* ^-- sementically equivalent to `123.f += 0.12f` */
解
在你的问题中你已经声明你已经知道这个问题的解决方法,但我想明确写出解决方案,以显示即使在强制转换产生不可修改的值时,如何修改ptr
值。
void*
是char*
类型一样
*((char**)&ptr) += numbytes; // make `ptr` move forward `numbytes`
( 注意 :当取消引用指针时,你得到一个左值 ,否则就不可能改变指向存储在指针中的地址的指向值的值。)
在=
的左侧,您需要一个lvalue
。 但是(char*)ptr
不是左值。
那是因为
(char*)ptr
不是左值。
试试这个:
void foo(void *ptr, int numBytes)
{
char* p = (char*)ptr;
p += numBytes;
}
更新
有关各种值类型的简要说明,请访问cppreference.com 。 这谈到了C ++中的值类型,但核心思想转化为C语言。
出于本次讨论的目的,
左值是一个表达式,用于标识非临时对象或非成员函数。
您可以获取左值的地址并分配给不同的值。
例:
int i;
int* p = &i;
i = 20;
相反,
prvalue(“纯”rvalue)是标识临时对象(或其子对象)的表达式,或者是与任何对象无关的值。
字面值42
是右值。 你做不到:
int* p = &42;
42 = 53;
在这一行中,
char* p = (char*)ptr;
从(char*)ptr
创建左值( p
)。 因此,可以使用:
p += numBytes;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.