Jump to content
Sign in to follow this  
vladislavbelov

C++ Tip #1: constant references

Recommended Posts

We talked with @elexis about constant references and I gave an example why passing by value may be better than passing by constant reference. During todays refactoring I met another important things that you need to know about constant references.

Aliasing

Take a look at the following code. Do you see a problem? (It's our code from ps/Shapes.h).

// Interface
class CSize
{
public:
    // ...
    void operator/=(const float& a);
  
    // ...
public:
    float cx, cy;
}

// Implementation
void CSize::operator/=(const float& a)
{
    cx /= a;
    cy /= a;
}

If not, would the following usage example help you?

CSize size(2560, 1440);
// Normalize the size.
if (size.cx)
    size /= size.cx;
debug_printf("%f %f", size.cx, size.cy);

You'll get:

1.0 1440.0

Because the a references to cx, and the first line of the operator modifies the cx. And in the next we just divide the cy by 1. It may happen in each case where we get the same class.

I fixed the problem in D1809.

Lifetime

Another important thing is a lifetime. Let's take another look at another example (fictional, because I didn't find more detailed example in our code yet):

std::vector<Node> nodes;
// ...
duplicate(nodes[0], 10);
// ...
void duplicate(const Node& node, size_t times)
{
    for (size_t i = 0; i < times; ++i)
        nodes.push_back(node);
}

From first look it seems ok. But, if you know how std::vector works then you know, that on each push_back std::vector can reallocate array to extend it. And then all iterators and raw pointers are invalid, including our constant reference. So after few duplication calls it may contain a trash.

So, you need to be careful with such cases.

  • Like 7

Share this post


Link to post
Share on other sites
7 hours ago, GunChleoc said:

For the duplicate function, resize and fill from the standard library should do the trick too - of course, with a copy instead of a reference.

http://www.cplusplus.com/reference/vector/vector/resize/

http://www.cplusplus.com/reference/algorithm/fill/

Yeah, every function that may invalidate the constant reference is potentially dangerous.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...