Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: returned value / temporary lifetime ?  (Read 1595 times)

0 Members and 1 Guest are viewing this topic.

joe5513

  • Newbie
  • *
  • Posts: 11
    • View Profile
returned value / temporary lifetime ?
« on: October 23, 2017, 01:49:01 pm »
I'm trying to figure why:

// m_vector is a std::vector<IntRect>
const IntRect& Animation::getFrame() const
{
return getEmpty() ? IntRect() : m_vector.at( *valid index in range from 0 to m_vector.size() - 1* );
}

// Assuming that Animation.getEmpty() returns false ...
//
// 1 this is working
Animation* animation = some_object.getAnimation();
IntRect f = animation->getFrame();
some_object.setTextureRect(f); // valid IntRect passed
//
// 2 but this is not
some_object.setTextureRect(some_object.getAnimation()->getFrame()); // invalid IntRect passed

Ive read about lvalues and rvalues but at this moment cant apply that knowlege to this particular problem.

So i hope someone can breefly explain me what difference is in provided examples and what i did wrong


« Last Edit: October 23, 2017, 03:16:37 pm by joe5513 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: returned value / temporary lifetime ?
« Reply #1 on: October 23, 2017, 02:38:47 pm »
What do you mean by "invalid" IntRect?

You shouldn't return by const reference when you're not always referencing an persisting object.
Your referenced object has to alive as long as the reference exists.
In case getEmpty() is true, then IntRect() will create a temporary object, which you then reference, but since the temp object gets destroyed at the end of the function, the referenced object is destroyed and you basically have undefined behavior.

Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

joe5513

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: returned value / temporary lifetime ?
« Reply #2 on: October 23, 2017, 03:14:21 pm »
What do you mean by "invalid" IntRect?

I mean in second example returned IntRect is random value, i understand it now, because reference to local are illegal

So i should explicitly create temporary variable and return it instead as const reference:

const IntRect& Animation::getFrame() const
{
        auto frame = IntRect();
        return getEmpty() ? frame : m_frames.at(m_index);
}

It working now, thanks!


eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: returned value / temporary lifetime ?
« Reply #3 on: October 23, 2017, 03:20:01 pm »
I don't think you got it. ;D

Before you returned reference to a "temporary variable" (rvalue), now you're just returning a reference to local variable, but the outcome is the same, as soon as the function returns, the local variable will get destroyed and the reference is invalidated.

Just return the IntRect as value.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

joe5513

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: returned value / temporary lifetime ?
« Reply #4 on: October 23, 2017, 03:39:51 pm »
Thank you so much! With your suggestions i found some information about that and NOW i can say i finally got it!

Just return the IntRect as value.

This is a solution for this particular problem.