Skip to content

clazy 1.2 released presenting 5 new Qt compile-time checks

In the previous episode we presented how to uncover 32 Qt best practices at compile time with clazy. Today it’s time to show 5 more and other new goodies present in the freshly released clazy v1.2.

New checks

1. connect-not-normalized

Warns when the content of SIGNAL(), SLOT(), Q_ARG() and Q_RETURN_ARG() is not normalized. Using normalized signatures allows to avoid unneeded memory allocations.

Example:

    // warning: Signature is not normalized. Use void mySlot(int) instead of void mySlot(const int) [-Wclazy-connect-not-normalized]
    o.connect(&o, SIGNAL(mySignal(int, int)),
              &o, SLOT(void mySlot(const int)));

See QMetaObject::normalizedSignature() for more information.

2. returning-data-from-temporary

Warns when returning the data from a QByteArray that will soon be destroyed. Accessing such data usually results in a crash. For example:

QByteArray b = ...;
return b.data();
return funcReturningByteArray().data();
return funcReturningByteArray().constData();
const char * getFoo()
{
    QByteArray b = ...;
    return b; // QByteArray can implicitly cast to char*
}
const char *c1 = getByteArray();
const char *c2 = str.toUtf8().data();

3. install-event-filter

Warns on potential misuse of QObject::installEventFilter(). To install an event filter on obj1 you should call obj1->installEventFilter(this), but sometimes you’ll write installEventFilter(obj1) by mistake, which compiles fine.

4. qcolor-from-literal

Warns when a QColor is being constructed from a string literal such as “#RRGGBB”. This is less performant than calling the ctor that takes ints, since it creates temporary QStrings.

Example:

QColor c("#000000"); // Use QColor c(0, 0, 0) instead
c.setNamedColor("#001122"); // Use c = QColor(0, 0x11, 0x22) instead

5. strict-iterators

Warns when iterator objects are implicitly cast to const_iterator. This is mostly equivalent to passing -DQT_STRICT_ITERATORS to the compiler, except that it also works for QString. This prevents detachments but also caches subtle bugs such as:

    QHash<int, int> wrong;
    if (wrong.find(1) == wrong.cend()) {
        qDebug() << "Not found";
    } else {
        // find() detached the container before cend() was called, so it prints "Found"
        qDebug() << "Found";
    }

    QHash<int, int> right;
    if (right.constFind(1) == right.cend()) {
        // Prints "Not Found". This is correct now !
        qDebug() << "Not found";
    } else {
        qDebug() << "Found";
    }

New features

1. clazy-standalone

Many people asked for clang-tidy support. This can’t be done due to clang-tidy not supporting plugins yet. Thus, clazy-standalone was born. It works in a similar way as clang-tidy, by operating on a json compilation database instead of being loaded as a compiler plugin. It can be invoked as:

 clazy-standalone -checks=level1 -p compile_commands.json myfile.cpp 

2. ASTMatchers

If you want to contribute a new check to clazy you can now use the AST Matchers API instead of the low level AST way. AST Matchers are gaining popularity and used in many clang tooling already.

3. Pre-built Windows binaries

Since it’s an hassle to build LLVM on your own on Windows, we’ve made a pre-built ready to use clazy v1.2 package.

The End

That’s all folks. You can get clazy from https://phabricator.kde.org/source/clazy/. Be sure to check the README.md file, it should have answers to most (clazy related) questions.

Please try it and report bugs!

Categories: KDAB on Qt / News / Qt / QtDevelopment / Tooling / Uncategorized

Tags: / / / /

7 thoughts on “clazy 1.2 released”

  1. “Warns when a QColor is being constructed from a string literal such as “#RRGGBB”. This is less performant”

    I’m wondering how did come about? How is has this become flagged as a big performance issue to warn about?

    I mean.. in UI there is tons and tons of things that you do for readabilty, code searchability and maintenance. If you use Qt’s CSS support, it makes sense to specify colors with the same notation.

    Under which scenario did constructing QColor become a performance bottleneck people need to avoid?

    One could avoid all of QML and do everythign in C++/QWidget, or avoid the CSS part of Qt to avoid “less performant” code, or every using QString and using const char* instead. There is no end “less performant” alternatives.

    1. Sérgio Martins

      >> I’m wondering how did come about?
      Usually these types of things are found by heaptrack, which identifies code that is calling malloc().

      >> How is has this become flagged as a big performance issue to warn about?
      It’s not a big performance issue.

      >> Under which scenario did constructing QColor become a performance bottleneck people need to avoid?
      It’s not a bottleneck, in fact clazy isn’t used for fixing bottlenecks, use a profiler for that. clazy is for tackling “death-by-a-thousand-cuts”. Please read https://www.kdab.com/use-static-analysis-improve-performance/
      But the basic theory is that if your app doesn’t have bottlenecks and is evenly slow, a profiler won’t identify anything.

      Although, to be fair, many of clazy’s checks have been seen under a profiler too, being bottlenecks.

      You can disable the qcolor check if it annoys you, real performance benefits can add up when you enable all 40-50 checks.

    1. Sérgio Martins

      I’ve never tried it.
      Clazy supports anything clang supports, if you can get clang >= 3.8 building with VS 2013 it will probably work.

  2. ahh I think you have to clarify your tool better.
    I though its just some standalone tool which I can run on every source code.

    But it is a compiler replacement for clang.

    1. Sérgio Martins

      It comes in two forms: a plugin for clang, and clazy-standalone.exe, which you can run on any source that’s buildable with clang.
      It’s explained in the readme.

  3. Clazy is a must-have in our company. Thanks for giving birth to such a useful tool. 🙂

    If you are looking for inspiration for new checks, maybe ask on the kde-i18n-doc mailing list.
    A few years ago, there were two or three things programmers got wrong that only broke translations. I think
    i18n(“foo %1”).arg(bar)
    was one of them. It had to be
    i18n(“foo %1”, bar)
    to work as expected. But well, I am away from i18n for some time and my knowledge is growing old. You might want to talk to Albert (aacid) about it.

    Cheers

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

By continuing to use the site, you agree to the use of cookies. More information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.

Close