C++ – Why a function returning by address can not be a lvalue

cfunctionsreferencereturn-type

Why is it not possible to set a function returning an address while it is possible to set a function that returns a reference.

int* returnByAddress()
{
    int x = 20;
    return &x;
}

int& returnByReference()
{
    int x = 30;
    return x;
}

int main()
{
    returnByReference() = 23; // possible
    int x = 23;
    returnByAddress() = &x;   // not a lvalue error 
    *returnByAddress() = 245; // possible

    return 0;
}

Best Answer

To start off, your code is broken. Returning a reference or the address of a local variable is returning garbage. Never do this. Here I've rewritten your example to return something real.

int xByAddress = 20;
int xByReference = 30;

int* returnByAddress()
{
    return &xByAddress;
}

int& returnByReference()
{
    return xByReference;
}

int main()
{
    returnByReference() = 23; //possible
    int x = 23;
    returnByAddress() = &x; //not a lvalue error 
    *returnByAddress() = 245; //possible

    return 0;
}

In this example, xByReference is assigned the value 23. xByAddress is assigned the value 245. Of course, returnByAddress() = &x; is invalid.

The rule is: functions return rvalues. The only way around this is to return a reference.

returnByAddress() returns a pointer by rvalue. You can deference the pointer to get an lvalue of the thing pointed at.

Following this rule, you can return a reference to the pointer.

int xByAddress = 20;
int *xPointer = nullptr;

int*& returnByPointerReference()
{
    xPointer = &xByAddress;
    return xPointer;
}

int main()
{
    int x = 23;
    returnByPointerReference() = &x; //not a lvalue error     
    return 0;
}

This code changes xPointer to point at the address of x.

Related Topic