Coo Misk
Coo Misk

Reputation: 1

error - c taking address of temporary

I'm getting a error in the following piece of code

void setStyle(const ctlStyleBase* style)
{
  //do something
}

void create(const ctlStyleBase* style = 0)
{
      if(style == 0) setStyle(&ctlStyleGradient());  // error : taking address of temporary
      else setStyle(style);
}

I don't think this is wrong, because I only use it in setStyle, and it won't get destructed before setStyle returns. Could some one tell me whether the code has some problems?

[compiler g++ 4.7.2]

Upvotes: 0

Views: 4045

Answers (3)

Jack Aidley
Jack Aidley

Reputation: 20107

You can do this:

void create(const ctlStyleBase* style = 0)
{
      if(style == 0)
      {
          ctlStyleGradient temp;
          setStyle(&temp);
      }
      else setStyle(style);
}

But, honestly, I would rework your code so you don't do this, passing pointers to local variables like this is risky business. Perhaps alter the setStyle call so that it checks for the null pointer?

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477228

Well, tough - it's a rule of the language that you cannot take the address of a temporary object. The reason for the rule is that there is basically never a good reason to do this.

In your example, ctlStyleGradient() returns some object of type ctlStyleBase. If you wanted to modify that object in the setStyle function (although you don't in this case), then as soon as you're done, the object ceases to exist, thus making the whole modification pointless.

Yes, you can contrive code where the operation has observable side effects, but that by itself would be very poor style. So, there's no deep technical reason why you shouldn't be able to take the address of a temporary, but the language decided not to let you do it because it's considered inappropriate.

But this doesn't seem what you're trying to do. Perhaps what you meant to do was for ctlStyleGradient() to return a pointer itself? Or, if you only need to observe a state and never change it, pass the state along by value or by const-reference.

Upvotes: 2

Joseph Mansfield
Joseph Mansfield

Reputation: 110698

The problem is that you simply cannot take the address of an rvalue expression. Your ctlStyleGradient returns a ctlStyleBase by value, copying it out of the function. This gives you a temporary and ctlStyleGradient() is an rvalue expression. You can't then do & on this expression.

If you don't need to modify the object that you pass to setStyle, then you can change it to take a const reference:

void setStyle(const ctlStyleBase& style)
{
  //do something
}

if(style == 0) setStyle(ctlStyleGradient());

If you do need to modify it, then you'll have to take a local copy of the ctlStyleBase object and pass that by value or reference:

void setStyle(ctlStyleBase style)
{
  //do something
}


if(style == 0) {
  ctlStyleBase styleCopy = ctlStyleGradient();
  setStyle(styleCopy);
}

Upvotes: 0

Related Questions