GCC 2.9和“左值作为左侧操作数所需的左值”

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

#include  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 *)?

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

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

例如:

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

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

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

那么, lvalue多少? 什么是modifiable-lvalue ? 请参阅维基百科:价值 。

它出于与原因相同的原因不起作用

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

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

旧的编译器(旧版本gcc)可能允许使用cast-as-lvalue,但是在新版本中已经删除了它,你可以找到它的cast-as-lvalue,conditional-expression-as-lvalue和compound-expression-as -lvalue扩展已在3.3.4和3.4中弃用,已被删除。

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

诀窍是投射到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