سؤال

I've wanted to apply unary '&' operator just behind function to operate on function return value. However, I get a compile-time error (I use gcc from MinGW)

test.c: In function 'main':

test.c:8:12: error: lvalue required as unary '&' operand

I made a code to make my question easier to understand:

int function();
void function2(int *param);

main()
{
    function2(&function1());
}

int function1()
{
    return 10;
}

void function2(int *param)
{
    return;
}

This code creates same compile-time error.

The question is: How I can use the '&' operator just from function2 "()", without other code elsewhere?

هل كانت مفيدة؟

المحلول

What you want can be achieved in C99 and later via:

function2((int[]){function1()});

i.e. making a compound literal containing the function return value.

نصائح أخرى

You can't. The return value of a function is a value but not an object. It has no designated location in memory, no address, and so you can't take a pointer to it. Instead you could write:

int a = function1();
function2(&a);

The problem is that & takes the address of variables. The return value of a function is not necessarily stored in memory. In other words, it is not an lvalue (you cannot put it on the left side of =). Therefore, it doesn't make sense to ask for its address (because it is non-existent).

What you should do is the following:

int result = function1();
function2(&result);

The C11 standard defines lvalue in 6.3.2.1 as:

An lvalue is an expression (with an object type other than void) that potentially designates an object; (footnote: The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object ‘‘locator value’’. What is sometimes called ‘‘rvalue’’ is in this International Standard described as the ‘‘value of an expression’’)

In the same standard, in 6.5.3.2 it says:

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.

You can't get the address of a value returned by a function.

What if that value is passed back to the caller via a CPU register?

The only way to make function2() use the result of function1() is to use an intermediate variable, which happens to have an address in memory.

main()
{
    int a;

    a = function1();
    function2(&a);
}

You cannot do this directly. The function return value may be stored on the stack (and will soon be overwritten in another function call), or maybe in the registers etc. (depending on the calling convention).

You probably don't want to directly access any of those places and it doesn't even make much sense (well, maybe unless you actually know what you're doing).

The return value of a function you work with is a rvalue (well... simply a value), while the '&' operator needs, as you have seen in the compiler output, a lvalue (something you can assign to). Ergo, just store the return value in a variable (a local variable inside your 'main()', then get the address of it).

int main() {
    int x = function1();
    function2(&x);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top