我正在尝试做一些相当简单的事情。当然可以使用额外的代码行完成,但从技术上讲,为什么这不起作用?
int foo = 5; int *bar = &(--foo);
GCC编译器告诉我"invalid lvalue in unary &"
答案 0 :(得分:5)
因为--foo
不是左值(因为它们通常出现在对齐的左侧,因此命名)。
与以下问题相同:
--foo = 7;
如果由于某些奇怪的原因,你需要在一行上,只需使用:
--foo; int *bar = &foo;
如果您认为在一个指令中需要它,再想一想。即使你制造了如此可怕的怪物(a),它也可能会编译成与上面代码片段相同的机器语言序列。
(a) int *bar = (--foo, &(foo));
答案 1 :(得分:2)
从技术上讲,它不起作用,因为--foo
不是左值,但是一元&
运算符需要一个。
根据C草案标准,第6.5.16节:
赋值表达式在赋值后具有左操作数的值,但不是左值。
虽然这不直接涵盖前缀减量运算符,但第6.5.3.1节使其适用:
表达式
++E
相当于(E+=1)
。
和
前缀
--
运算符类似于前缀++
运算符,除了操作数的值递减。
当然,第6.5.3.2节:
一元
&
运算符的操作数应该是函数指示符,[]
或一元*
运算符的结果,或者是指定不是对象的对象的左值位字段,不使用register
存储类说明符声明。
答案 2 :(得分:1)
因为--foo
会返回一些时间值,但&
需要一个变量来创建对它的引用。因此,您需要分两步完成:
int *bar = &foo;
--foo;
答案 3 :(得分:0)
因为(--foo)是rvalue。像数字常量
答案 4 :(得分:0)
我不知道为什么你可能需要这样做;但如果指针应该相等。如果在语句(逗号分隔)中执行,则语句中的最后一个元素是返回的内容。根据GCC,以下编译和两个变量相等。
int main(int argc, char *argv[]) {
int foo = 5;
int *bar;
printf("%p\n", &foo);
bar = (int *)(--foo, &foo);
printf("%p\n", bar);
return -1;
}