Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"expression must be an l-value or function designator" error when taking the address of this

I'm trying to do this in C++:

class Abc
{
   int callFunction1()
};

void function1(Abc** c1) {//do something}

int Abc::callFunction1()
{
   function1(&this);
   return 0;
}

And I get "expression must be an l-value or function designator" error in visual studio 2015. So I don't understand where I go wrong. To my knowledge, &this should have the type Abc** right?

The function definition isn't mine to change. So I can't just change the parameter type.

like image 742
disccip Avatar asked Sep 20 '17 19:09

disccip


3 Answers

The error is clear enough. Since this is not an lvalue, you cannot take its address. If you just want the address of the object, then just pass this, not &this, and change the function declaration to:

void function1(Abc* c1) //To just pass a pointer

However, since you mentioned you cannot change the definition of the function, you can create a temporary variable and pass its address:

auto temp = this;
function1(&temp);

How this works:

  1. Since this is a prvalue and cannot have its address taken, you need something to point to it to turn it into an lvalue, here temp.
  2. Now that temp points to this, taking temp's address will effectively take this's address, albeit indirectly.
  3. Therefore, since you are passing the address of an lvalue to function1, the code compiles and works as expected.
like image 189
Arnav Borborah Avatar answered Oct 21 '22 03:10

Arnav Borborah


From the C++ Standard (9.2.2.1 The this pointer)

1 In the body of a non-static (9.2.1) member function, the keyword this is a prvalue expression whose value is the address of the object for which the function is called.

and (5.3.1 Unary operators)

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

To make it more clear consider the following code snippet.

If for example you have a declaration

int x = 10;

then you may not write

int **p = &&x;

In the right expression &x is a prvalue and according to the second quote from the Standard you may not apply the unary operator & to the prvalue.

You could write

int *q = &x;
int **p = &q;

because q is lvalue.

like image 41
Vlad from Moscow Avatar answered Oct 21 '22 05:10

Vlad from Moscow


The expression this is an rvalue, the same way that the expressions 137 or 'a' are, and so you can't take its address.

If you want to get a pointer to a pointer to this, you'll need to create a new variable of the right type:

auto* ptr = this;
doSomething(&ptr);
like image 4
templatetypedef Avatar answered Oct 21 '22 03:10

templatetypedef