Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Don't call QString::operator[]() on temporary

Tags:

c++

qt

I run clazy on my code and get warning about such code:

QChar value() const
{
    if (hide_content_)
        return '\0';
    else
        return text()[0];
}

where text() has such signature QString text() const;

warning is:

warning: Don't call QString::operator[]() on temporary
      [-Wclazy-detaching-temporary]
            return text()[0];
                   ^

But what does it mean? Is it possible that temporary QString object will be destroyed before call to operator[]?

like image 200
user1244932 Avatar asked Feb 20 '18 01:02

user1244932


1 Answers

Is it possible that temporary QString object will be destroyed before call to operator[]?

No, the warning is not about being an unsafe operation. Behavior here is completely defined as temporaries aren't destroyed until the end of the full expression in which they are created (i.e. until the end of the return statement in your case).

Summary: The warning is about performance issues associated with the operation. You can fix it by using .at(0) instead of .operator[](0). For an explanation continue reading the answer.


First of all, Qt's containers are implicitly shared; meaning that when you copy a container, its elements aren't actually copied until a write operation is performed on the container (aka. copy-on-write).

This means that the container needs to detach (perform a deep copy) whenever it detects a write operation, so that this implicit sharing remains transparent to the user.

And this includes cases when the container hands out non-const references to items inside it (exactly what non-const operator[] is doing), as it can't know in advance how you (the container user) will actually use these non-const references.

In other words, Let's say we have a QString str = "abc"; when you write QChar ch = str[0];, QString's non-const operator[] gets called and, to the container, this is exactly what it gets to know when a user writes str[0] = 'x';. This means that the container needs to detach whenever a non-const operation is called on it. It is the job of the user to use a const function when he/she isn't really going to change anything in the container.

Clazy here is trying to detect cases when users get a non-const reference inside a temporary (since it doesn't really make sense to mutate a temporary that is about to get destroyed soon).


For more information:

  1. Uncovering 32 Qt best practices at compile time with clazy - see #8
  2. Effective Qt - Marc Mutz - Meeting C++ 2015
like image 124
Mike Avatar answered Sep 24 '22 22:09

Mike