Better_Software_Header_MobileBetter_Software_Header_Web

Find what you need - explore our website and developer resources

Uncovering 32 Qt best practices at compile time with clazy

Generating compile-time warnings and automatic refactoring for Qt best practices

 connect(obj, &MyObj::mySlot, &MyObj::mySlot2); 

int a;
connect(obj, &MyObj::mySignal, [&a] { ... });

    for (auto value : myMap.values()) // Bad
    for (auto value : myMap) // Good, no temporary allocations

    // Also no allocations, but iterating keys now
    for (auto it = map.keyBegin(), end = map.keyEnd(); it != end; ++it)

    int n = set.toList()[0]; // Bad
    int n = set.constFirst(); // Good

    if (hash.keys().contains(key)) // Bad
    if (hash.contains(key)) // Good

    int sz = hash.values().size(); // Bad
    int sz = hash.size(); // Good

    hash.values().contains(v); // Bad, use std::find() instead

    mySets.intersect(other).isEmpty() // Bad
    !mySets.intersects(other) // Good


// temporary list returned by function
QList<int> getList()
{
    QList<int> list;
    ... add some items to list ...
    return list;
}

for (auto it = getList().begin(); it != getList().end(); ++it)
{
    ...
}



QList<SomeType> MyClass::getList()
{
   // Qt uses implicit sharing, so the list's element aren't actually copied, unless...
    return m_list;
}

void bad()
{
    // Ouch, triggers deep-copy of all elements, use constFirst() instead.
     SomeType t = myClass.getList().first();
}


    // Bad, implies a malloc() call and filling a temporary container
    qDeleteAll(bananas.values());

    // Good
    qDeleteAll(bananas);

    // Bad, implies a malloc() call and filling a temporary container
    qDeleteAll(oranges.keys());

    // Good
    qDeleteAll(oranges.keyBegin(), oranges.keyBegin());

    // Potential deep-copy
    for (auto item : m_items)

    // Good
    for (auto item : qAsConst(m_items))

    // Bad, should probably by passed by <em>const-ref</em>
    for (auto v : getQVariants())

    // Bad, QDateTime::currentDateTimeUtc().toTime_t() is faster
    QDateTime::currentDateTime().toTime_t()

    // Bad, QDateTime::currentDateTimeUtc() is faster
    QDateTime::currentDateTime().toUTC()

    QString("%1 %2").arg(a).arg(b); // Bad
    QString("%1 %2").arg(a, b); // one less temporary heap allocation

    str.mid(5).toInt(ok) // Bad
    str.midRef(5).toInt(ok) // Good

    // Oops, path is not what you expect it to be
    const auto path = "hello " +  QString::fromLatin1("world");
    qDebug() << path; // Crash if you're using QStringBuilder

25 Comments

18 - Apr - 2017

Andy

20 - Apr - 2017

Sérgio Martins

24 - Apr - 2017

Andy

19 - Apr - 2017

Nierob

const auto path = "hello " +  QString::fromLatin1("world");
qDebug() << path; // Crash if you're using QStringBuilder

19 - Apr - 2017

Andrew Gunnerson

20 - Apr - 2017

Sérgio Martins

20 - Apr - 2017

Laszlo Nagy

20 - Apr - 2017

Kevin Funk

20 - Apr - 2017

Sérgio Martins

20 - Apr - 2017

CarelC

20 - Apr - 2017

Sérgio Martins

20 - Apr - 2017

Henry Miller

20 - Apr - 2017

Kevin Funk

export CLAZY_CHECKS="level0,no-qenums" # Enables all checks from level0, except for qenums

20 - Apr - 2017

Markus

20 - Apr - 2017

Sérgio Martins

20 - Apr - 2017

Markus

20 - Apr - 2017

Sergio Martins

21 - Apr - 2017

Markus

24 - Apr - 2017

Kuba Ober

24 - Apr - 2017

Sérgio Martins

24 - Apr - 2017

Serhii

22 - Jan - 2018

William

22 - Jan - 2018

Sérgio Martins

23 - Jan - 2018

William

23 - Jan - 2018

Sérgio Martins

SérgioMartins

Sérgio Martins

Senior Software Engineer

Learn Modern C++

Learn more