void foo(void *ptr, int numBytes)
{
(char*)ptr += numBytes;
}
这不用C语言编译。我知道替代方案。但为什么这不起作用?有什么问题?
答案 0 :(得分:4)
问题
问题是(char*)ptr
不会产生左值,这意味着该值无法修改 - 人们可以将其视为演员的临时结果,演员表将产生一个类型为char*
的 rvalue 。
它在语义上与您拥有以下示例一样,转换产生临时值,这样的值不能分配新值。
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`
(注意:取消引用指针时会得到左值,否则无法更改指向值的值位于存储在指针中的地址。)
答案 1 :(得分:3)
在=
的左侧,您需要lvalue
。但(char*)ptr
不是左值。
答案 2 :(得分:3)
那是因为
(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;
从p
创建左值((char*)ptr
)。因此,可以使用:
p += numBytes;