Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this is causing C2102: '&' requires l-value

Tags:

c++

I was wondering, why the following way of code (Already commented out) will cause
C2102: '&' requires l-value

Is there a better way to avoid using tmp variable?

class a {
private:
    int *dummy;
public:
    int* get_dummy() const {
        return dummy;
    }
};

int main()
{
    a aa;

    // error C2102: '&' requires l-value
    //int** me = &(aa.get_dummy());

    // OK!
    int *tmp = aa.get_dummy();
    int** me = &(tmp);
}
like image 858
Cheok Yan Cheng Avatar asked Sep 09 '10 07:09

Cheok Yan Cheng


1 Answers

The compiler is right, according to ISO C++ § 5.3.1.3:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id.

In other words, you can take an address of anything that has a name.

Values returned from functions by-value have no name and are often returned via a register. So there is no "address" to speak of as the value is not residing in memory!

One could argue that the compiler could be smarter, detect this and store the value on the stack for the duration of the expression in which the address is used. But that is error-prone (you can "leak" a pointer to outside the expression), and would clearly be an extension of the standard (i.e. not guaranteed to be compatible). So MSVC simply prohibits it.

Entertainingly, the compiler is that smart when it comes to a reference to an rvalue. But there is no such functionality for a pointer to an rvalue.

To answer your question: try to minimize taking addresses of stuff; taking an address of a variable prevents the optimizer from putting it into a register. But if you have to, return a reference instead:

class a {
private:
    int dummy;
public:
    int get_dummy() const {
        return dummy;
    }
    int& get_dummy() {
        return dummy;
    }
};

int main()
{
    a aa;

    int* me = &(aa.get_dummy());
}

Note that having a const get_dummy() is not strictly needed, but will help the optimizer in rvalue contexts.

like image 158
rustyx Avatar answered Oct 31 '22 11:10

rustyx