我一直在使用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>
答案 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