Take the 2-minute tour ×

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 &"

share|improve this question
add comment

5 Answers

up vote 5 down vote accepted

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));

share|improve this answer
Could also do: int *bar = --foo, &foo;. –  GManNickG Mar 30 '11 at 3:13
Close, @GMan, problematic since I think the comma is being taken as a declaration separator rather than the comma operator, but you can get around that by enclosing the whole lot within parentheses. Still, if someone bought that code to me for review, I'd have quite a lot of fun that day :-) –  paxdiablo Mar 30 '11 at 3:18
Oh duh, right you are. –  GManNickG Mar 30 '11 at 3:22
The reason I was trying to it was because I wanted to say function(&(--foo)) because I wanted to pass the value of (foo-1) by reference to the function. Of course, its horrible code, but I really wondering from a theory point. –  eternalmatt Mar 30 '11 at 20:22
add comment

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 makes it apply:



The prefix -- operator is analogous to the prefix ++ operator, except that the value of the operand is decremented.

And, of course, section


share|improve this answer
add comment

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;
share|improve this answer
add comment

because (--foo) is rvalue. like a number constant

share|improve this answer
add comment

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 foo = 5;
        int *bar;
        printf("%p\n", &foo);
        bar = (int *)(--foo, &foo);
        printf("%p\n", bar);
        return -1;
share|improve this answer
add comment

Your Answer


