GCC 2.9和“左值作为赋值的左值”

时间:2013-12-19 07:21:35

标签: c gcc

我一直在使用void指针并创建了这个例子:

#include <stdio.h>

struct intint {
    int a;
    int b;
};

struct intshortshort {
    int a;
    short b;
    short c;
};

void fill_me(struct intint **pii, void *piss)
{
    (void*)*pii = piss;                // Question about this line?
}

int main()
{
    struct intint *pii = NULL;
    struct intshortshort iss;
    iss.a = iss.b = iss.c = 13;

    fill_me(&pii, &iss);

    printf("%d..%d\n", pii->a, pii->b);


    return 0;
}

问题:

当我使用gcc版本2.95.4时,所有内容都按预期编译并运行,但gcc版本4.7.3给出了以下错误:

void_pointer.c:16:17: error: lvalue required as left operand of assignment

是否有理由不再允许向左值添加(void *)?

编辑:感谢您的回答,我想我理解了这个问题,但问题“为什么一开始就没问题?”仍然很有趣。< / p>

5 个答案:

答案 0 :(得分:3)

这个问题不是关于void*,而是关于类型转换和左值。

例如:

#include <stdio.h>

int main()
{
    int n;
    (int)n = 100;
    return 0;
}

此代码将导致相同的错误:左值作为赋值的左操作数需要左值。

那是因为=运算符需要一个可修改的左值作为其左操作数。

那么,lvalue是什么?什么是modifiable-lvalue?请参阅wikipedia:Value

答案 1 :(得分:2)

它不起作用的原因与

相同
  int x, y;
  (int)x = y;

不起作用。演员表的结果不是“左值”,它不会保存一个内存位置,您可以在其中存储内容。而是将(int)x的结果视为临时的,不可见的变量,仅在执行此操作期间存在。

答案 2 :(得分:2)

旧编译器(旧版本gcc)可能允许使用cast-as-lvalue,但在新版本中已删除它,您可以找到它The cast-as-lvalue, conditional-expression-as-lvalue and compound-expression-as-lvalue extensions, which were deprecated in 3.3.4 and 3.4, have been removed.

答案 3 :(得分:0)

您不能在C中的赋值运算符的左操作数上使用强制运算符。

答案 4 :(得分:0)

诀窍是转换为void**,然后取消引用它:

void fill_me(struct intint **pii, void*piss)
{
        *(void **)pii=piss;
}

按预期输出:

13..851981

13 is obvious
851,981 - 13 = 851,968
851,968 / (256*256) = 13
there are the 2 shorts as an int