繁体   English   中英

为什么我不能对void指针的强制转换进行算术运算?

[英]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值。

  1. 指针的地址变为void
  2. 将此地址转换为指向char的指针
  3. 取消引用指针,产生指向char指针
  4. 修改此yield 左值 ,就好像原始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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM