Reputation: 3564
I'm trying to do something fairly simple. Of course it could be done with an extra line of code, but technically speaking, why does this not work?
int foo = 5; int *bar = &(--foo);
GCC compiler tells me "invalid lvalue in unary &"
Upvotes: 1
Views: 113
Reputation: 4423
I have no clue why you might need to do this; but if the pointers should be equal. If you do it in a statement ( comma delimited) then the last element in the statement is what is returned. The following compiles and both variables are equal according to 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;
}
Upvotes: 0
Reputation: 94834
Technically speaking, it doesn't work because --foo
is not an lvalue, but the unary &
operator requires one.
From the C draft standard, section 6.5.16:
An assignment expression has the value of the left operand after the assignment, but is not an lvalue.
While that doesn't directly cover the prefix decrement operator, section 6.5.3.1 makes it apply:
The expression
++E
is equivalent to(E+=1)
.
and
The prefix
--
operator is analogous to the prefix++
operator, except that the value of the operand is decremented.
And, of course, section 6.5.3.2:
The operand of the unary
&
operator shall be either a function designator, the result of a[]
or unary*
operator, or an lvalue that designates an object that is not a bit-field and is not declared with theregister
storage-class specifier.
Upvotes: 2
Reputation: 882226
Because --foo
is not an lvalue (so named since they typicaly appeared on the left of an asignment).
It's the same problem with:
--foo = 7;
If, for some bizarre reason, you need it on one line, just use:
--foo; int *bar = &foo;
If you think you need it in one instruction, think again. Even if you make such a horrible monstrosity (a), it will probably compile down to the same machine language sequence as that code snippet above.
(a) int *bar = (--foo, &(foo));
Upvotes: 5
Reputation: 1644
Because --foo
returns some temporal value, but &
needs a variable to create a reference to it. So, you need do it in two steps:
int *bar = &foo;
--foo;
Upvotes: 1