开发者

Why does this C not allow combining -- operator and & operator in this syntax

I'm trying to do something fairly simple. Of course it could be done with an extra line of code, but开发者_JAVA技巧 technically speaking, why does this not work?

int foo = 5;
int *bar = &(--foo);

GCC compiler tells me "invalid lvalue in unary &"


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


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 the register storage-class specifier.


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;


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


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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜