Skip to content

C++

QCOMPARE with Custom Qt Types

When you write unit tests, you will have to compare the actual value and the expected value. A simplified example with QStrings would look like this.

void MyTest::testQCompare() {
    auto actualStr = QString{"abba"};
    auto expectedStr = QString{"juhu"};
    QCOMPARE(actualStr, expectedStr);
}

When you run this unit test, the QTest framework will print the actual value "abba" and the expected value "juhu". This is often enough to know what went wrong.

FAIL!  : MyTest::testQCompare() Compared values are not the same
   Actual   (actualStr)  : "abba"
   Expected (expectedStr): "juhu"

If two values of a custom type differ, the QTest framework will only print the first line: Compared values are not the same. This is not very helpful. How can you make QCOMPARE print the actual and expected for custom types as well?

Read More »QCOMPARE with Custom Qt Types

Printing Custom Qt Types with qDebug()

When you define your own C++ types for a Qt application, you want to print their values with qDebug(), qWarning() or qCritical() eventually.

auto frame1 = QCanBusFrame{0x18ef0201U, QByteArray::fromHex("018A010000000000")};
qDebug() << "frame1 =" << frame1;

The C++ compiler will complain with this error message:

error: no match for ‘operator<<’ (operand types are ‘QDebug’ and ‘QCanBusFrame’)

The error message tells you to write your own output operator for the QDebug stream and for QCanBusFrame.

A custom C++ type that wants to play nicely with Qt should always define a QDebug output operator. Even the developers of the Qt library seem to forget it sometimes, as the example of QCanBusFrame shows.

Read More »Printing Custom Qt Types with qDebug()

QML Engine Deletes C++ Objects Still In Use

Correction: In the original post, I stated that ownership is transferred from C++ to QML by READ functions of Q_PROPERTYs. This is wrong. Ownership is only transferred by Q_INVOKABLE functions and slots, which return a QObject pointer. I corrected my post and my code example. Now, the simple code example crashes as desired. Many thanks to Richard and Simon for pointing out my mistake.

I recently spent three days on a customer project to figure out why my QML application crashed with a segmentation fault. The crash happened after a long sequence of interactions, which was hard to reproduce. I finally managed to reproduce the crash reliably after going through the same six-step interaction four times.

After many hours of debugging and scrutinising my code, I had an epiphany about the stack trace leading to the crash. The stack trace originated from deep inside the QML engine and ended in calling the destructor of a C++ object, which was still in use on the C++ side. The trace never touched any of the application’s C++ code in between.

So far, I had only asked myself the question: Where in my C++ code do I corrupt the memory? After my little epiphany, I changed my question: Why does the QML engine delete a C++ object still in use? What do I overlook in the interaction between QML and C++?
Read More »QML Engine Deletes C++ Objects Still In Use

Best Friends: C++11 Move Semantics and Pimpl

Move semantics is faster than copy semantics, when the compiler can replace expensive copy operations by cheaper move operations, that is, when it can replace a deep copy of a big object by a shallow copy of the pointer to the big object. Hence, classes using the pimpl idiom in combination with move semantics should see a considerable speed-up. As Qt applies the pimpl idiom consistently to every non-trivial Qt class, we should see a speed-up by simply using Qt classes instead of their STL counterparts. I’ll compare the performance of classes that use move semantics with Qt and STL classes with and without applying the pimpl idiom.
Read More »Best Friends: C++11 Move Semantics and Pimpl

Performance Gains Through C++11 Move Semantics

We explore when and how our code benefits most from equipping classes with move constructors and assignment operators. We analyse in detail, which constructors and assignment operators (move or copy) are called for C++98 and C++11 when we insert or emplace objects into containers, when we initialise containers and when we shuffle and sort containers. Finally, we run benchmarks for these operations and discuss the actual speed-up, which ranges from 1% to 70%.
Read More »Performance Gains Through C++11 Move Semantics

Simplifying Loops with C++11 in Qt Ways

Recently, I looked through the code base of a medium-sized project to see how I could simplify handwritten for-loops by using C++11’s new range-based for and STL algorithms with lambda expressions. The results in short: Range-based for makes loops simpler, easier to understand and often faster. STL algorithms are often a bit harder to read and write than range-based for loops, because lambda expressions are pretty clumsy, algorithm naming is inconsistent, and algorithm interfaces are inconvenient. But, they are still better than handwritten for-loops.
Read More »Simplifying Loops with C++11 in Qt Ways

Remote Support for Harvester Terminal via VNC

The maize harvest is in full swing. The harvester runs nearly 24/7. The driver notices a drop in the area cut per hour. He calls tech support and starts sharing the screen of the terminal in the harvester. The support technician guides guides the driver through changing some machine parameters. All is fine again. My Italian business partner, Ispirata, and I developed a VNC server for the Freescale i.MX53 terminal of Krone’s BiGX forage harvester – to make this scenario possible.
Read More »Remote Support for Harvester Terminal via VNC