C - 表达式必须是可修改的左值

jay*_*pee 6 c pointers void-pointers

我很困惑为什么我的编译器在以下情况下抛出错误:

void funcExample (void * p_Buf, uint16_t len) 
{
    uint16_t i;

    for (i = 0; i < len; i++) {
        otherFunc (((uint8_t *)p_Buf)++); //error = expression must be a modifiable lvalue
    }
}
Run Code Online (Sandbox Code Playgroud)

但是如果我在传递给otherFunc之前进行转换,那很好,因为增加非void指针没有问题:

void funcExample (void * p_Buf, uint16_t len) 
{
    uint16_t i;
    uint8_t * p_Buf_8bit;

    p_Buf_8bit = (uint8_t *) p_Buf;   

    for (i = 0; i < len; i++) {
        otherFunc (p_Buf_8bit++); 
    }
}
Run Code Online (Sandbox Code Playgroud)

一旦施放,无法将void指针递增?我错过了一些基本的东西吗?

250*_*501 5

c中的演员运营商:

6.5.4.p5通过带括号的类型名称在表达式之前,将表达式的值转换为命名类型.这种结构称为演员.104)指定没有转换的强制转换对表达式的类型或值没有影响.

104)演员不会产生左值.因此,对合格类型的强制转换与对该类型的非限定版本的强制转换具有相同的效果

但是一元运算符++需要一个左值,如下所述:

6.5.3.1.p1前缀增量或减量运算符的操作数应具有原子,限定或非限定的实数或指针类型,并且应为可修改的左值.

因此你可以这样做:

p_Buf = ( uint8_t* )p_Buf + 1 ;
Run Code Online (Sandbox Code Playgroud)

p_Buf左值在哪里,( uint8_t* )p_Buf是右值.


我要注意,在你的第二个例子中你没有演员(如你所说),但是你声明了一个uint8_t指针.然后当你使用++它时,你不执行任何强制转换(因为它具有正确的类型)并且操作有效.