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

disccip picture disccip · Sep 20, 2017 · Viewed 19.7k times · Source

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.

Answer

Arnav Borborah picture Arnav Borborah · Sep 20, 2017

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.