<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>KDAB</title><description>Discover the depth of KDAB expertise in software. From Qt framework to C++ and Rust, from Operating Systems to GUI frameworks. From troubleshooting to complete project development. Get the software expertise you require to succeed.</description><link>https://www.kdab.com/</link><language>en-gb</language><item><title>Bind QML Values across an Arbitrary Number of Elements</title><link>https://www.kdab.com/bind-qml-values-across-an-arbitrary-number-of-elements/</link><guid isPermaLink="true">https://www.kdab.com/bind-qml-values-across-an-arbitrary-number-of-elements/</guid><description>&lt;p data-block-key=&quot;rlqes&quot;&gt;Synchronize properties across dynamically instantiated QML elements, using a C++ singleton that acts as a message broker and recursive signal-slot connections. This design enables flexible and scalable value synchronization across components, with minimal coupling between UI and logic.&lt;/p&gt;</description><pubDate>Thu, 19 Mar 2026 08:26:39 GMT</pubDate><content:encoded>&lt;h1&gt;Bind QML Values across an Arbitrary Number of Elements&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;gg3t3&quot;&gt;A while back I was writing a program that could instantiate an arbitrary number of windows containing controls synchronized across them. How a control would be synchronized would depend on a condition that determined which window instances would be linked to other instances. There are a few ways this could be implemented. In this entry I&apos;ll share my approach, in which I used a singleton C++ class serving as a message broker to bind properties across window instances.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Properties bound across multiple instances of a window_1_QML_Blog_Javier&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Properties_bound_across_multiple_instances_of_a.original.jpg&quot; class=&quot;Properties bound across multiple instances of a window_1_QML_Blog_Javier&quot; alt=&quot;Properties bound across multiple instances of a window_1_QML_Blog_Javier&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;gjgxd&quot;&gt;Properties bound across multiple instances of a window&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;the-app:-display-to-light-panels&quot; data-block-key=&quot;4wd6v&quot;&gt;The App: Display to Light Panels&lt;/h2&gt;&lt;p data-block-key=&quot;770kf&quot;&gt;The software I wrote this for is a small app that allows you to have many windows open, all synchronized to display a single color on a per-monitor basis. The idea behind this is for users to adjust the light that comes off their monitors and use it to illuminate their faces when recording a video or taking pictures. By having individual windows be synchronized, users can continue to interact with the computer through their displays (rather inconveniently), while simultaneously using them to illuminate themselves.&lt;/p&gt;&lt;p data-block-key=&quot;clvra&quot;&gt;This is, by no means, a replacement for a proper recording setup. Some of you will know that a light source placed in front of the subject can serve as either a nice &quot;fill light&quot; or a &quot;scary spotlight&quot;, depending on the height and size of the source. Therefore, this should be complemented with other sources of light; ideally ambient light and a top light, to achieve a nice look. If the app seems useful to you, there&apos;s a link to it at the end of this article. That&apos;s enough gaffer speak for today. Let&apos;s talk about the code.&lt;/p&gt;&lt;h2 id=&quot;the-code&quot; data-block-key=&quot;4ug9g&quot;&gt;The Code&lt;/h2&gt;&lt;p data-block-key=&quot;6u7bp&quot;&gt;When writing code, one of my main concerns is always long-term maintainability. For that reason, I prefer to connect different parts of code in explicit, and easy to follow ways. One of such ways is passing values through a hierarchy of components; that is generally easy to track and produces well performing code. However, that approach can become unviable when connecting dynamically instantiated items to other dynamically instantiated items. A better solution in this instance is to use signals and slots to interconnect the items via a message broker class, done in C++. Each item would have a model or backend class in C++ and those classes would have the message broker in common. Lastly, the properties would be exposed to QML through &lt;code&gt;Q_PROPERTY&lt;/code&gt; and updated via your control&apos;s signal handlers.&lt;/p&gt;&lt;h2 id=&quot;message-broker-singleton&quot; data-block-key=&quot;01urs&quot;&gt;Message Broker Singleton&lt;/h2&gt;&lt;p data-block-key=&quot;fa272&quot;&gt;The message broker needs to be a singleton. That way there&apos;s only one instance of the broker in memory and all instantiated objects interface with the same broker. Our message broker only needs to provide the signals that will be used for routing properties. The actual connections that the routing involves are to be done from the outside. As such, a broker class would look like this:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// internalmessagebroker.hpp
// Singleton broker class contains signals that serve as pipes
// for different parts of a program to communicate with each other.

#pragma once

#include &amp;lt;QObject&amp;gt;

class InternalMessageBroker : public QObject
{
    Q_OBJECT

// Hide regular constructor
private:
    InternalMessageBroker() = default;

public:
    // Disable copy constructor
    InternalMessageBroker(const InternalMessageBroker&amp;amp; obj) = delete;
    InternalMessageBroker&amp;amp; operator=(InternalMessageBroker const&amp;amp;) = delete;
    static std::shared_ptr&amp;lt;InternalMessageBroker&amp;gt; instance()
    {
        static std::shared_ptr&amp;lt;InternalMessageBroker&amp;gt; sharedPtr{new InternalMessageBroker};
        return sharedPtr;
    }

// This is where all the signals would go
signals:
    void broadcastAPropertyChange(int value, bool broadcast);
};&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;connecting-properties&quot; data-block-key=&quot;qnyhk&quot;&gt;Connecting Properties&lt;/h2&gt;&lt;p data-block-key=&quot;57h0&quot;&gt;Then we have the class or classes that would connect the properties together. On my Display Panels app, all controls and visual features come from QML, meaning I only have to concern myself with interconnecting the properties. To that end, I&apos;ve created a class based on &lt;code&gt;QObject&lt;/code&gt; and instantiated it within the delegate of a QML Instantiator. This class is only for managing property data, so I refer to it as a model class, called &lt;code&gt;PropertiesModel&lt;/code&gt;:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-qml  line-numbers &quot;&gt;// Main.qml
// Here are 3 windows, each with a PropertiesModel,
// that allows them all to share a binding to aProperty
// across all window instantiatons.

import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Controls

import com.kdab.example

Item {
    Instantiator {
        model: 3
        delegate: Window {
            PropertiesModel {
                id: propertiesModel
                aProperty: 1
            }
            ColumnLayout {
                anchors.fill: parent
                Text {
                    text: propertiesModel.aProperty
                }
                Slider {
                    id: hueSlider
                    value: propertiesModel.aProperty
                    Layout.fillWidth: true
                    onMoved: {
                        propertiesModel.aProperty = value;
                    }
                }
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;669ti&quot;&gt;Each property of our class is to be declared using a &lt;code&gt;Q_PROPERTY&lt;/code&gt; macro with a getter, a setter, and a notifier. The getter and the notifier have nothing out of the ordinary...&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// An ordinary getter
int PropertiesModel::aProperty()
{
    return m_aProperty;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;




&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// An ordinary notifier, form propertiesmodel.h
signals:
    void aPropertyChanged();&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;669ti&quot;&gt;However, the setter must be able to distinguish between when its call is the product of a user interaction and when it comes from the message broker. We accomplish this by having the setter accept a boolean argument (broadcast) that will be used to determine whether the value being set should be sent through the message broker or notified back to QML for the UI to be updated. When a setter is first called, the value being set should be broadcasted and only on its way back should the UI be updated.&lt;/p&gt;&lt;p data-block-key=&quot;7krnb&quot;&gt;There are a few ways we could make sure that the value is always broadcasted first. We could set broadcast to true by default, or have two setter functions: a private one taking in both the value and broadcast arguments and a public one that only takes-in the value and calls the private function with broadcast set to true. Another option is to have broadcast be an enum with only two possible values. That would produce more readable code, however, I didn&apos;t worry about that in my code because broadcast is only to be used on calls to the private setter.&lt;/p&gt;&lt;p data-block-key=&quot;2ij84&quot;&gt;Upon the private setter being called by the public setter, it will emit the broker&apos;s broadcast signal and that signal will in turn call the calling private setter for a second time (as well as the private setters of all other instances of &lt;code&gt;PropertiesModel&lt;/code&gt;; those being called for the first time). When the private setter calls the broker that calls back to the private setter, it also passes broadcast set to false. All other instances will then evaluate the value of broadcast to be false determining that the UIs should be updated and preventing an infinite loop.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Private setter implementation for a property that&amp;#x27;s being broadcasted
void PropertiesModel::setAProperty(const int value, const bool broadcast)
{
    if (broadcast)
        emit m_broker.get()-&amp;gt;broadcastAPropertyChange(value, false);
    else if (m_currentScreen == screenName) {
        m_aProperty = value;
        emit screenSaturationChanged();
    }
}

// Publicly exposed setter prevents the broadcast argument from being
// specified by other callers
void PropertiesModel::setAProperty(const int value)
{
    // Always broadcast properties not being set by the message broker
    setAProperty(value, true);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;669ti&quot;&gt;To complete this loop as described, we need to connect the signal from the broker to the private setter of the &lt;code&gt;PropertiesModel&lt;/code&gt; class whenever a new copy is instantiated. The best place to accomplish that is from the class&apos; constructor, like so:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// The constructor is used to connect signals from the broker to setter properties
PropertiesModel::PropertiesModel(QObject* parent)
    : QObject { parent }
{
    m_mb = InternalMessageBroker::instance();
    // Connections take place after the class has been instantiated
    // and its QML properties parsed.
    QTimer::singleShot(0, this, [this] () {
        connect(m_mb.get(), &amp;amp;InternalMessageBroker::aPropertyChange,
        this, &amp;amp;ScreenModel::setAProperty);
    });
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;qtimer-to-delay-initialization&quot; data-block-key=&quot;f44wk&quot;&gt;QTimer to Delay Initialization&lt;/h2&gt;&lt;p data-block-key=&quot;7r9tu&quot;&gt;If you&apos;ve been reading the blocks of code that accompany this article, you may be wondering &quot;Why is there a &lt;code&gt;singleShot&lt;/code&gt; &lt;code&gt;QTimer&lt;/code&gt; there?&quot; When the &lt;code&gt;PropertiesModel&lt;/code&gt; class is instantiated via QML, any connected properties that have values assigned from QML code will trigger the &lt;code&gt;Q_PROPERTY&lt;/code&gt;&apos;s setter function. This will happen once per instantiation. If the broker were connected, it would broadcast the value set to all currently instantiated instances every single time that a new instance is added. To prevent that, we must not make the connection to the broker until after a class has been fully initialized. A single shot timer can be used to accomplish that; setting its delay to 0 will ensure that it is run immediately after all properties have been evaluated.&lt;/p&gt;&lt;p data-block-key=&quot;dlka2&quot;&gt;In the end, this is what the &lt;code&gt;PropertyMode&lt;/code&gt;l header would look like:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// propertiesmodel.h
#pragma once

#include &amp;quot;internalmessagebroker.hpp&amp;quot;

#include &amp;lt;QQmlEngine&amp;gt;

class PropertiesModel : public QObject {
    Q_OBJECT
    QML_ELEMENT

    Q_PROPERTY(int aProperty READ aProperty WRITE setAProperty NOTIFY aPropertyChanged FINAL)
public:
    explicit PropertiesModel(QObject* parent = nullptr);

    int aProperty();
    void setAProperty(const int value);

signals:
    void aPropertyChanged();

private: 
    void setAProperty(const int value, const bool broadcast);

    std::shared_ptr&amp;lt;InternalMessageBroker&amp;gt; m_mb;
    int m_aProperty;
};&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;conditional-propagation&quot; data-block-key=&quot;0xkmg&quot;&gt;Conditional propagation&lt;/h2&gt;&lt;p data-block-key=&quot;aoaf7&quot;&gt;If a condition must be met for the propagated value to result in an update, then, in addition to &lt;i&gt;value&lt;/i&gt; and &lt;i&gt;broadcast&lt;/i&gt;, you should also broadcast any other values that are required to for such condition to be met. Pass those as arguments to the setter&apos;s and the broker&apos;s signal. Condition validation would then take place within the base case of the private setter. Here&apos;s a commented snippet of what that looks like on the Display to Light Panels app that this article was based on:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// In the original code what here I named broadcast used to be named spread.
void ScreenModel::setScreenHue(const int hue, const bool spread=true, const QString &amp;amp;screenName=&amp;quot;s&amp;quot;)
{
    if (spread)
        emit m_mb.get()-&amp;gt;spreadHueChange(hue, false, m_currentScreen);
    // The incoming value is only accepted if screenName matches the screen
    // that the window is at and discarded otherwise.
    else if (m_currentScreen == screenName) {
        m_screens[m_currentScreen].hue = hue;
        emit screenHueChanged();
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;




&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Properties bound across instances of a window_2_QML_Blog_Javier&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Properties_bound_across_instances_of_a_window.original.jpg&quot; class=&quot;Properties bound across instances of a window_2_QML_Blog_Javier&quot; alt=&quot;Properties bound across instances of a window_2_QML_Blog_Javier&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;gjgxd&quot;&gt;Properties bound across instances of a window&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;real-world-example&quot; data-block-key=&quot;fgh11&quot;&gt;Real World Example&lt;/h2&gt;&lt;p data-block-key=&quot;cbkgp&quot;&gt;For a real world application, you can read the code for Display to Light Panels, the app that inspired this article, at: &lt;a href=&quot;https://github.com/Cuperino/Display-to-Light-Panels&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;https://github.com/Cuperino/Display-to-Light-Panels&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;82jef&quot;&gt;If you need help solving architecture problems, such as this one, reach out to us and we will gladly find ways in which we can help.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/bind-qml-values-across-an-arbitrary-number-of-elements/&quot;&gt;Bind QML Values across an Arbitrary Number of Elements&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>c++</category><category>desktop</category><category>qml</category><category>qt</category><category>ux/ui</category></item><item><title>Hotspot v1.6.0 released</title><link>https://www.kdab.com/hotspot-v1-6-0-released/</link><guid isPermaLink="true">https://www.kdab.com/hotspot-v1-6-0-released/</guid><description>&lt;p data-block-key=&quot;1sw01&quot;&gt;Hotspot is a standalone GUI designed to provide a user-friendly interface for analyzing performance data. It takes a perf.data file, parses and evaluates its contents, and presents the results in a visually appealing and easily understandable manner. Our goal with Hotspot is to offer a modern alternative to perf report, making performance analysis on Linux […]&lt;/p&gt;</description><pubDate>Fri, 13 Mar 2026 07:19:47 GMT</pubDate><content:encoded>&lt;h1&gt;Hotspot v1.6.0 released&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;3x6h0&quot;&gt;&lt;a href=&quot;https://www.kdab.com/hotspot-video/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Hotspot&lt;/a&gt; is a standalone GUI designed to provide a user-friendly interface for analyzing performance data. It takes a &lt;code&gt;perf.data&lt;/code&gt; file, parses and evaluates its contents, and presents the results in a visually appealing and easily understandable manner. Hotspot’s goal is to offer a modern alternative to &lt;code&gt;perf report&lt;/code&gt;, making performance analysis on Linux systems more intuitive and efficient.&lt;/p&gt;&lt;p data-block-key=&quot;c275l&quot;&gt;Version 1.6.0 introduces powerful new features, improved workflows, and numerous bug fixes to make profiling even smoother.&lt;/p&gt;&lt;h2 id=&quot;changelog-for-hotspot-v1.6.0&quot; data-block-key=&quot;39oj1&quot;&gt;ChangeLog for Hotspot v1.6.0&lt;/h2&gt;&lt;p data-block-key=&quot;duuev&quot;&gt;&lt;a href=&quot;https://github.com/KDAB/hotspot/releases/tag/v1.6.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;This release&lt;/a&gt; focuses on usability improvements and extended analysis capabilities. The most notable additions are:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;8eokv&quot;&gt;Support for archived perf files (e.g. &lt;code&gt;perf.data.zip&lt;/code&gt;)&lt;/li&gt;&lt;li data-block-key=&quot;6s6o4&quot;&gt;Regex filtering in the flamegraph&lt;/li&gt;&lt;li data-block-key=&quot;6dmsd&quot;&gt;Tracepoint support&lt;/li&gt;&lt;li data-block-key=&quot;fkvnu&quot;&gt;Various bug fixes and stability improvements&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;open-archived-perf-files-directly&quot; data-block-key=&quot;dw1a8&quot;&gt;Open Archived perf Files Directly&lt;/h2&gt;&lt;p data-block-key=&quot;7v5j4&quot;&gt;Hotspot can now open perf recordings stored inside archives such as &lt;code&gt;perf.data.zip&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;23rsk&quot;&gt;This simplifies sharing profiling results, storing CI artifacts, and working with compressed recordings - no manual extraction required.&lt;/p&gt;&lt;h2 id=&quot;regex-in-the-flamegraph&quot; data-block-key=&quot;hupsd&quot;&gt;Regex in the Flamegraph&lt;/h2&gt;&lt;p data-block-key=&quot;81umj&quot;&gt;The Flamegraph view now supports &lt;b&gt;regular expression filtering&lt;/b&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;2el70&quot;&gt;This makes it much easier to:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;gn9m&quot;&gt;Match complex symbol patterns&lt;/li&gt;&lt;li data-block-key=&quot;5m0p9&quot;&gt;Focus on specific subsystems or namespaces&lt;/li&gt;&lt;li data-block-key=&quot;1qokc&quot;&gt;Quickly narrow down large profiling datasets&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;6s8g3&quot;&gt;Especially for large C++ codebases, regex search significantly speeds up navigation.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Hotspot_V1.6.0_Regex_Example&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Clipboard_-_March_3_2026_1_17_PM.original.png&quot; class=&quot;Hotspot_V1.6.0_Regex_Example&quot; alt=&quot;Hotspot_V1.6.0_Regex_Example&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;gcck3&quot;&gt;Regex in the flamegraph&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;tracepoint-support&quot; data-block-key=&quot;6ua5w&quot;&gt;Tracepoint Support&lt;/h2&gt;&lt;p data-block-key=&quot;243vm&quot;&gt;Hotspot 1.6.0 introduces support for &lt;b&gt;tracepoints&lt;/b&gt; captured via &lt;code&gt;perf&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;6ps2v&quot;&gt;This enables analysis of event-based data in addition to traditional sampling, giving deeper insight into system and runtime behavior.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Hotspot_V1.6.0_Tracepoints_Example&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Clipboard_-_March_3_2026_1_23_PM.original.png&quot; class=&quot;Hotspot_V1.6.0_Tracepoints_Example&quot; alt=&quot;Hotspot_V1.6.0_Tracepoints_Example&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;gcck3&quot;&gt;Tracepoints&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;bug-fixes-and-improvements&quot; data-block-key=&quot;2yvln&quot;&gt;Bug Fixes and Improvements&lt;/h2&gt;&lt;p data-block-key=&quot;eh5nf&quot;&gt;As usual, this release also includes numerous smaller fixes, UI refinements, and internal cleanups to improve overall stability and user experience.&lt;/p&gt;&lt;p data-block-key=&quot;a8i75&quot;&gt;For a complete overview of all changes, see the &lt;a href=&quot;https://github.com/KDAB/hotspot/releases/tag/v1.6.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;full changelog&lt;/a&gt; on GitHub.&lt;/p&gt;&lt;p data-block-key=&quot;csck&quot;&gt;Happy profiling!&lt;/p&gt;&lt;h2 id=&quot;videos&quot; data-block-key=&quot;uvkg0&quot;&gt;Videos&lt;/h2&gt;&lt;p data-block-key=&quot;dmlud&quot;&gt;Hotspot - A GUI for perf report:&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/6ogEkQ-vKt4?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Hotspot – A GUI for perf report&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;3x6h0&quot;&gt;Hotspot Demo from Embedded World 2022:&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/1_EOIsg89GA?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Hotspot Demo&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;


&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/hotspot-v1-6-0-released/&quot;&gt;Hotspot v1.6.0 released&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator><category>c++</category><category>desktop</category><category>linux</category><category>open source</category><category>performance</category><category>tools</category><category>ux/ui</category></item><item><title>Weighing up Zngur and CXX for Rust/C++ Interop</title><link>https://www.kdab.com/weighing-up-zngur-and-cxx-for-rustc-interop/</link><guid isPermaLink="true">https://www.kdab.com/weighing-up-zngur-and-cxx-for-rustc-interop/</guid><description>&lt;p data-block-key=&quot;hga1v&quot;&gt;A detailed comparison of Zngur and CXX for Rust/C++ interoperability, exploring their design philosophies, container support, trait objects, async capabilities, build systems, and real-world tradeoffs.&lt;/p&gt;</description><pubDate>Thu, 05 Mar 2026 08:13:33 GMT</pubDate><content:encoded>&lt;h1&gt;Weighing up Zngur and CXX for Rust/C++ Interop&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;With Rust consistently proving itself as a good replacement for C++ due to its type system, memory safety, and macros, many industry giants are starting to write or rewrite things in this more modern systems language.&lt;/p&gt;&lt;p data-block-key=&quot;3t3l4&quot;&gt;That being said, the maturity, and broad ecosystem of C++ cannot be understated, and many companies have decades of code written in established C++ tech stacks, for example the Qt framework. This is where interoperability comes in, allowing Rust&apos;s modern features and package management to be paired with existing C++ knowledge and codebases, or call rigorously tested and optimised C++ libraries in a new Rust codebase.&lt;/p&gt;&lt;p data-block-key=&quot;bm1d0&quot;&gt;Now that &lt;a href=&quot;https://cxx.rs/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CXX&lt;/a&gt; - the most widely adopted Rust with C++ interop library - is mature and kept very stable, we would like to explore &lt;a href=&quot;https://crates.io/crates/zngur&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Zngur&lt;/a&gt;, another emerging library in this space.&lt;/p&gt;&lt;h2 id=&quot;design-philosophies&quot; data-block-key=&quot;2kdtf&quot;&gt;Design Philosophies&lt;/h2&gt;&lt;p data-block-key=&quot;569hm&quot;&gt;One important differentiator between these libraries is their aims, with Zngur attempting to support a larger subset of semantics, with the cost of some performance, ergonomics and safety, whereas CXX preaches safety and a reduced feature set, with the claim of no overhead. As stated in the &lt;a href=&quot;https://hkalbasi.github.io/zngur/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Zngur documentation&lt;/a&gt;:&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;73p99&quot;&gt;&quot;Zngur also makes safety guarantees but also tries to be powerful enough to handle arbitrary signatures from Rust code&quot;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;One example where Zngur is less restrictive than CXX is that it permits owned objects across the FFI boundary, using the &lt;code&gt;#cpp_value&lt;/code&gt; directive. Zngur also avoids guarantees around &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; as we will discuss in the multithreading section.&lt;/p&gt;&lt;p data-block-key=&quot;dqtjq&quot;&gt;I personally found Zngur a little easier to set up, but it does have a more convoluted way of specifying the language boundary, which is explained below. Additionally, Zngur aims to keep most of the generated and glue code in the C++ side, as opposed to splitting it over Rust and C++, and this can potentially make it easier to debug, but also eschews some of Rust&apos;s safety guarantees. On the other hand, the many thousands of lines of C++ code can sometimes be redundant and difficult to search through.&lt;/p&gt;&lt;h2 id=&quot;technical-dive&quot; data-block-key=&quot;3oj06&quot;&gt;Technical Dive&lt;/h2&gt;&lt;p data-block-key=&quot;fjvcj&quot;&gt;Now let&apos;s get into the nitty-gritty details of this comparison that separate these two frameworks. Zngur poses some advantages over CXX with more arbitrary container support, and trait implementations with dynamic dispatch. On the other hand, CXX has a more solid build setup, much larger community, and external support for async Rust, all of which we will explore below.&lt;/p&gt;&lt;h3 id=&quot;containers&quot; data-block-key=&quot;8melw&quot;&gt;Containers&lt;/h3&gt;&lt;p data-block-key=&quot;cdp3l&quot;&gt;One of Zngur&apos;s selling points is its claim to support most container types with &quot;almost full API&quot;, whereas CXX has a more limited selection. Some of these types include nesting vectors such as &lt;code&gt;Vec&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;HashMap&amp;lt;K, V&amp;gt;&lt;/code&gt;, and &lt;code&gt;Arc&amp;lt;dyn T&amp;gt;&lt;/code&gt; (we will discuss trait objects next).&lt;/p&gt;&lt;p data-block-key=&quot;66uuk&quot;&gt;This first class support comes with a cost, however, as each type needs to be manually specified, e.g. &lt;code&gt;Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;&lt;/code&gt; and &lt;code&gt;Vec&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;&lt;/code&gt; need to be separately declared (and even &lt;code&gt;String&lt;/code&gt; needs to be declared). This quickly compounds, as for each type, you must specify all std library methods you want to use, which can lead to very large files.&lt;/p&gt;&lt;p data-block-key=&quot;d9u57&quot;&gt;CXX has good support for many container types with &quot;out of the box&quot; use, and more complex types can be wrapped with the newtype pattern, and used opaquely, with slightly reduced ergonomics. CXX also has the very powerful feature of being able to automatically generate the appropriate specializations for the types you need. In most cases, CXX has enough support for standard containers - and makes using them a lot simpler - but if your app is going to have a lot of complex types, you may be better going with Zngur.&lt;/p&gt;&lt;h4 id=&quot;nested-vectors-in-zngur&quot; data-block-key=&quot;6dxfa&quot;&gt;Nested Vectors in Zngur&lt;/h4&gt;&lt;p data-block-key=&quot;7a06u&quot;&gt;Here we have an example IDL (interface description language) file declaring a 2D vector. Zngur uses separate files for it&apos;s boundary description, whereas CXX has the bridge macro, but these perform the same role.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;// Exposes nested vector types
mod vec {
    type Vec&amp;lt;i32&amp;gt; {
        #layout(size = 24, align = 8);
        wellknown_traits(Debug);
        fn new() -&amp;gt; Vec&amp;lt;i32&amp;gt;;
        fn push(&amp;amp;mut self, i32);
        fn len(&amp;amp;self) -&amp;gt; usize;
    }

    type Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt; {
        #layout(size = 24, align = 8);
        wellknown_traits(Debug);
        fn new() -&amp;gt; Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;;
        fn push(&amp;amp;mut self, Vec&amp;lt;i32&amp;gt;);
        fn len(&amp;amp;self) -&amp;gt; usize;
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/prelude.zng#L20-L45&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;See here for the full file&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;f0kb8&quot;&gt;We can construct, move, and call functions with the type in C++ like&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;auto row1 = to_vec({1,0,0});
auto row2 = to_vec({0,2,0});
auto row3 = to_vec({0,0,1});

auto matrix1 = Vec&amp;lt;Vec&amp;lt;int32_t&amp;gt;&amp;gt;::new_();
auto matrices = Vec&amp;lt;Vec&amp;lt;Vec&amp;lt;int32_t&amp;gt;&amp;gt;&amp;gt;::new_();

matrix1.push(std::move(row1));
matrix1.push(std::move(row2));
matrix1.push(std::move(row3));

matrices.push(std::move(matrix1));

zngur_dbg(rust::crate::determinants(matrices));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/main.cpp#L47-L71&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;eu7j2&quot;&gt;The template has been declared in C++ to shorten &lt;code&gt;rust::std::vec::Vec&amp;lt;T&amp;gt;&lt;/code&gt;, and the &lt;code&gt;to_vec&lt;/code&gt; helper is used so rows can be created with initializer lists.&lt;/p&gt;&lt;p data-block-key=&quot;6ocai&quot;&gt;The Rust function is simply calculating matrix determinants, and performing this on a vector of matrices. This way we make use of 1D, 2D and 3D vectors across the boundary.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;/// Treating nested vector like a 3x3 matrix, returns list of 
pub fn determinants(matrices: &amp;amp;Vec&amp;lt;Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;&amp;gt;) -&amp;gt; Vec&amp;lt;i32&amp;gt; {
    let mut result = vec![];
    for m in matrices {
        // Naming components to make formula easier to read
        let a = m[0][0];
        // ...
        let i = m[2][2];

        let det = a*e*i + b*f*g + c*d*h - (c*e*g + a*f*h + b*d*i);
        result.push(det);
    }

    result
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/src/nested_types.rs#L4-L31&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;h4 id=&quot;nested-vectors-in-cxx&quot; data-block-key=&quot;bme3x&quot;&gt;Nested Vectors in CXX&lt;/h4&gt;&lt;p data-block-key=&quot;6hjo1&quot;&gt;CXX does not support bridging arbitrary containers, but this can easily be remedied using the newtype pattern. Although they must then be opaque, you can put more complex containers behind a struct, and pass that over the boundary, like so:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;// We define a newtype, and can give it some basic methods
#[derive(Debug)]
struct Matrix {
    inner: Vec&amp;lt;Vec&amp;lt;i32&amp;gt;&amp;gt;,
}

impl Matrix {
    fn get_row(&amp;amp;self, row: usize) -&amp;gt; &amp;amp;Vec&amp;lt;i32&amp;gt; {
        &amp;amp;self.inner[row]
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L35-L44&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;73dkj&quot;&gt;And then adding some C++ code, we can use this newtype to perform some calculations&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// We use an app class to hold our methods
ExampleApp::ExampleApp() {}

std::unique_ptr&amp;lt;ExampleApp&amp;gt; new_app() {
  return std::unique_ptr&amp;lt;ExampleApp&amp;gt;(new ExampleApp());
}

// Calculating the determinants the same as the Zngur example
int32_t ExampleApp::calculate_determinant(const Matrix &amp;amp;m) const {
  auto row0 = m.get_row(0);
  auto row1 = m.get_row(1);
  auto row2 = m.get_row(2);
  
  // We can use the index operator, because CXX maps Rust Vec to C++ vector, something not possible in Zngur
  auto a = row0[0];
  // ...
  auto i = row2[2];

  auto det = a*e*i + b*f*g + c*d*h - (c*e*g + a*f*h + b*d*i);
  return det;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/example.cc#L5-L27&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;1ib1l&quot;&gt;We then specify the boundary using the CXX bridge macro:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;#[cxx::bridge]
mod ffi {
    extern &amp;quot;Rust&amp;quot; {
        type Matrix;
        fn get_row(self: &amp;amp;Matrix, row: usize) -&amp;gt; &amp;amp;Vec&amp;lt;i32&amp;gt;;
    }

    unsafe extern &amp;quot;C++&amp;quot; {
        include!(&amp;quot;cxx-example/include/example.h&amp;quot;);
        type ExampleApp;

        fn new_app() -&amp;gt; UniquePtr&amp;lt;ExampleApp&amp;gt;;
        fn calculate_determinant(&amp;amp;self, matrix: &amp;amp;Matrix) -&amp;gt; i32;
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L3-L16&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;s7hr&quot;&gt;This can then be called like so in our main function:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;fn main() {
    let app = ffi::new_app();
    let m = vec![vec![1, 2, 3], vec![4, 5, 0], vec![0, 0, 9]];
    let mat = Matrix { inner: m };
    let det = app.calculate_determinant(&amp;amp;mat);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L46-L52&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;cjfkh&quot;&gt;Although similar, both approaches have their strengths and weaknesses.&lt;/p&gt;&lt;h3 id=&quot;enums&quot; data-block-key=&quot;xbm0w&quot;&gt;Enums&lt;/h3&gt;&lt;p data-block-key=&quot;d2btp&quot;&gt;Whilst CXX has support for basic Rust enums, Zngur&apos;s built-in support for tagged union type enums (variants that contain data) is very powerful for Rust users.&lt;/p&gt;&lt;p data-block-key=&quot;5tsbq&quot;&gt;This means that defining &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Result&amp;lt;T, E&amp;gt;&lt;/code&gt; in your crate is trivial, and these are two of the most used data types in Rust. This includes constructors, e.g. instantiating &lt;code&gt;Ok(value)&lt;/code&gt; in C++ code. Of course, the developer still needs to specify that they want to use these types in the IDL file.&lt;/p&gt;&lt;p data-block-key=&quot;70kdn&quot;&gt;On the other hand, the CXX community has a solution for this, in that if you need support for more than basic enums, there exists &lt;a href=&quot;https://crates.io/crates/cxx-enumext&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;cxx-enumext&lt;/a&gt;, which provides the support for much more complex enums, including data with lifetimes, and boxed data. There is certainly something to be said for Zngur&apos;s wider support for declaring these algebraic data types, however.&lt;/p&gt;&lt;h3 id=&quot;traits&quot; data-block-key=&quot;cbn0m&quot;&gt;Traits&lt;/h3&gt;&lt;p data-block-key=&quot;dv0md&quot;&gt;Another strength of Zngur&apos;s is implementing traits in C++. For example, as a replacement for abstract classes or interfaces, you can define a Rust trait, and implement it in C++, for either Rust or C++ types, allowing polymorphism over the boundary via constructing a &lt;code&gt;Box&amp;lt;dyn MyTrait&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;d233c&quot;&gt;For example, as a replacement for abstract classes or interfaces, you have two options when it comes to traits:&lt;/p&gt;&lt;ol&gt;&lt;li data-block-key=&quot;c5ddp&quot;&gt;Implement your trait for &lt;b&gt;Rust&lt;/b&gt; objects using &lt;i&gt;C++&lt;/i&gt;&lt;/li&gt;&lt;li data-block-key=&quot;bbdqg&quot;&gt;Implement your trait for a &lt;i&gt;C++ class&lt;/i&gt;, by inheriting from it in &lt;i&gt;C++&lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p data-block-key=&quot;70dov&quot;&gt;One caveat to this, however, is that Zngur provides a &lt;code&gt;make_box&lt;/code&gt; C++ helper for using these objects polymorphically, but is only accessible to C++ classes that inherit from a trait, not Rust objects with Rust or C++ implementations. This does, however, seem like something that could be easily rectified in the future. Our workaround for this, is simply adding a method to your trait like so:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;trait MyTrait {
    // Your trait methods here
    fn as_my_trait(self) -&amp;gt; Box&amp;lt;dyn MyTrait&amp;gt; where Self: Sized + &amp;#x27;static { 
        Box::new(self)
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;In CXX this type of behaviour would be done via a &lt;code&gt;UniquePtr&lt;/code&gt; instead and a C++ base class. This has its benefits and tradeoffs, but the first class support for trait objects in Zngur bodes well for leveraging the power that traits bring. Moreover, C++ lambdas can be turned into &lt;code&gt;Box&amp;lt;dyn Fn&amp;gt;&lt;/code&gt; objects, allowing them to be passed to Rust functions like &lt;code&gt;map&lt;/code&gt; like a Rust closure.&lt;/p&gt;&lt;p data-block-key=&quot;5ipef&quot;&gt;With this IDL definition:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;mod crate {
    // Declaring the methods we want to use in the trait
    trait MediaType {
        fn author(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn title(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn rating(&amp;amp;self) -&amp;gt; u8;
        fn media_type(&amp;amp;self) -&amp;gt; ::std::string::String;
    }

    // Box type must be declared too
    type Box&amp;lt;dyn crate::MediaType&amp;gt; {
        #layout(size = 16, align = 8);
    }

    // A rust function to display Movies, Songs, Albums, and any new media types
    // Simply prints out the author, title and rating in a pretty format
    fn display_media(Box&amp;lt;dyn MediaType&amp;gt;);

    type Movie {
        #layout(size = 56, align = 8);
        wellknown_traits(Debug);

        constructor {author_name: ::std::string::String, movie_title: ::std::string::String, movie_rating: u8};
        fn as_boxed(self) -&amp;gt; Box&amp;lt;dyn MediaType&amp;gt; use MediaType; // The use keyword specifies this method comes from the trait

        field author_name (offset = 0, type = ::std::string::String);
        field movie_title (offset = 24, type = ::std::string::String);
        field movie_rating (offset = 48, type = u8);
    }

    type Song {
        #layout(size = 56, align = 8);
        wellknown_traits(Debug);

        constructor {author: ::std::string::String, title: ::std::string::String, rating: u8};

        field author (offset = 0, type = ::std::string::String);
        field title (offset = 24, type = ::std::string::String);
        field rating (offset = 48, type = u8);
    }
}

// This block declares that we are going to implement the trait using C++
// This is done using the Impl template provided by Zngur
extern &amp;quot;C++&amp;quot; {
    impl crate::MediaType for crate::Movie {
        fn author(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn title(&amp;amp;self) -&amp;gt; ::std::string::String;
        fn rating(&amp;amp;self) -&amp;gt; u8;
        fn media_type(&amp;amp;self) -&amp;gt; ::std::string::String;
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/trait_objects.zng&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full File Here&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;911qt&quot;&gt;We can implement traits for our Rust types using C++ like so&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Trait impls
String
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::author(
    rust::Ref&amp;lt;Movie&amp;gt; self) {
    // String have to be clone to be owned in C++ since they are allocated by the rust heap, so cannot be moved easily
  return self.author_name.clone();
}

String
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::title(
    rust::Ref&amp;lt;Movie&amp;gt; self) {
  return self.movie_title.clone();
}

String
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::media_type(
    rust::Ref&amp;lt;Movie&amp;gt; _self) {
  return &amp;quot;Cinema&amp;quot;_rs.to_owned();
}

uint8_t
rust::Impl&amp;lt;Movie, MediaType&amp;gt;::rating(
    rust::Ref&amp;lt;Movie&amp;gt; self) {
  return self.movie_rating;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/main.cpp#L93-L117&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;6a64d&quot;&gt;We can then access boxed trait objects in a few ways:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;28c8&quot;&gt;Inherit from the trait, and use the make_box helper&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Implementing MediaType for rust::Song
class SongMedia : public MediaType {
  Song song;

public:
  SongMedia(Song s) : song(std::move(s)) {}

 ...
};

...

// Create an instance from a rust::Song
auto song_media = SongMedia(std::move(song));

// Call its methods
auto artist = song_media.author();
zngur_dbg(artist);

// Get a boxed trait object using the Zngur helper
auto boxed_song_media = Box&amp;lt;Dyn&amp;lt;MediaType&amp;gt;&amp;gt;::make_box&amp;lt;SongMedia&amp;gt;(std::move(song_media));
display_media(std::move(boxed_song_media));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/main.cpp#L21-L45&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;2qcqe&quot;&gt;Use the rust trait implementation&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Using the rust as_boxed method as shown above (called as_boxed here)
auto my_album_as_media_type = my_album.as_boxed();
display_media(std::move(my_album_as_media_type));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;ul&gt;&lt;li data-block-key=&quot;oqsck&quot;&gt;Use the C++ trait implementation&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// display_media will use the C++ implentations, but note as_boxed comes from the trait in Rust.
auto my_movie_as_media_type = jaws.as_boxed();
display_media(std::move(my_movie_as_media_type));&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;mgy12&quot;&gt;Note that the trait contains an implemented method as_boxed, so C++ implementations can use it: &lt;code&gt;fn as_boxed(self) -&amp;gt; Box&amp;lt;dyn MediaType&amp;gt; where Self: Sized + &apos;static { Box::new(self) }&lt;/code&gt;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;These 3 options permit flexible use of traits implemented in Rust or C++.&lt;/p&gt;&lt;p data-block-key=&quot;eqnbm&quot;&gt;In CXX, we use a different idiom, defining a base class, and then using &lt;code&gt;UniquePtr&lt;/code&gt; to get access to it in Rust.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;// Abstract base / interface
class Media {
    public:
        virtual rust::String media_type() const = 0;
        virtual rust::String author() const = 0;
        virtual rust::String title() const = 0;
        virtual int rating() const = 0;
        const Media&amp;amp; as_media() const { return *this; }
};&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/include/media.h#L7-L14&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Complete Header File&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;cr465&quot;&gt;This acts as our &quot;trait&quot; since we need to override the virtual methods, and the as_media method is available on inheritors. It use the dereference in the return so that it can be coerced into the base class.&lt;/p&gt;&lt;p data-block-key=&quot;62qsa&quot;&gt;We can then define our inheriting classes:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;class Movie : public Media {
public:
    Movie(rust::String title, rust::String author, int rating) : m_title(std::move(title)), m_author(std::move(author)), m_rating(rating) {}
    rust::String author() const override {
        return m_author;
    }

    rust::String title() const override {
        return m_title;
    }

    rust::String media_type() const override {
        return rust::String(&amp;quot;Movie&amp;quot;);
    }

    int rating() const override {
        return m_rating;
    }

private:
    rust::String m_title;
    rust::String m_author;
    int m_rating;
};&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;And do the same for our Song class.&lt;/p&gt;&lt;p data-block-key=&quot;ep66v&quot;&gt;We can then define our methods to obtain a unique pointer:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;std::unique_ptr&amp;lt;Movie&amp;gt; make_movie(rust::String title, rust::String author, int rating) {
    return std::make_unique&amp;lt;Movie&amp;gt;(title, author, rating);
}

std::unique_ptr&amp;lt;Song&amp;gt; make_song(rust::String title, rust::String author, int rating) {
    return std::make_unique&amp;lt;Song&amp;gt;(title, author, rating);
}

// function to print all media types in a readable manner
void display_media(const Media&amp;amp; m) {
    ...
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;&lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/example.cc#L29-L44&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Full Example&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;30iv0&quot;&gt;We can then expose them in the bridge of the &lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/src/main.rs#L18-L32&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;main file&lt;/a&gt; like so:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;#[cxx::bridge]
mod ffi {
    unsafe extern &amp;quot;C++&amp;quot; {
        include!(&amp;quot;cxx-example/include/media.h&amp;quot;);

        type Media;
        type Movie;
        type Song;

        fn make_movie(title: String, author: String, rating: i32) -&amp;gt; UniquePtr&amp;lt;Movie&amp;gt;;
        fn make_song(title: String, author: String, rating: i32) -&amp;gt; UniquePtr&amp;lt;Song&amp;gt;;

        fn as_media(self: &amp;amp;Movie) -&amp;gt; &amp;amp;Media;
        fn as_media(self: &amp;amp;Song) -&amp;gt; &amp;amp;Media;

        fn display_media(m: &amp;amp;Media);
    }
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;And use them in main,&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;fn main() {
    // Media
    let jaws = make_movie(&amp;quot;Jaws&amp;quot;.to_owned(), &amp;quot;Steven Spielberg&amp;quot;.to_owned(), 8);
    let fur_elise = make_song(&amp;quot;Fur Elise&amp;quot;.to_owned(), &amp;quot;Mozart&amp;quot;.to_owned(), 5);

    display_media(jaws.as_ref().unwrap().as_media());
    display_media(fur_elise.as_ref().unwrap().as_media());
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;async-and-threading&quot; data-block-key=&quot;izn2c&quot;&gt;Async and Threading&lt;/h3&gt;&lt;p data-block-key=&quot;a75ab&quot;&gt;On the other side of the coin, CXX has support for async rust &lt;a href=&quot;https://cxx.rs/async.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;planned&lt;/a&gt;, allowing async functions to be simply declared in the bridge, but currently they offer a workaround for calling async functions via a new type struct, containing a &lt;a href=&quot;https://docs.rs/futures/latest/futures/channel/oneshot/index.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;oneshot channel&lt;/a&gt; (futures crate). Furthermore, the &lt;a href=&quot;https://crates.io/crates/cxx-async&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;cxx-async&lt;/a&gt; crate adds support for async tasks, and is fairly well established, so it can be a robust addition to your project if you need async.&lt;/p&gt;&lt;p data-block-key=&quot;fqvm8&quot;&gt;Zngur on the other hand does not have this support planned, and makes no mention of how to implement it yourself. Zngur also doesn&apos;t do any checks, however, around &lt;code&gt;Send&lt;/code&gt; and &lt;code&gt;Sync&lt;/code&gt; - despite having support for &lt;code&gt;Arc&amp;lt;T&amp;gt;&lt;/code&gt; (a smart pointer used in threaded situations), as opposed to CXX&apos;s static assertions, which make multithreaded situations much safer.&lt;/p&gt;&lt;h3 id=&quot;project-setup&quot; data-block-key=&quot;2hkxt&quot;&gt;Project Setup&lt;/h3&gt;&lt;p data-block-key=&quot;17f46&quot;&gt;A further benefit of CXX is its significantly higher adoption - being used in Chromium and Android - as well as its better written and more complete documentation. We did find that Zngur had a slightly simpler project setup, being that you can simply generate the glue code, then use your existing C++ build setup, along with cargo to generate a library, or alternatively compile a C++ library, and link to your Rust binary. This independence from a specific build system makes it quick to integrate with what your already have. It also has the added benefit of not requiring any dependencies, simply being a CLI tool which generates the glue code for you.&lt;/p&gt;&lt;p data-block-key=&quot;6k31l&quot;&gt;As we have often seen with CXX throughout the blog, this functionality does exist in some form, namely the &lt;code&gt;cxxbridge&lt;/code&gt; command. This allows you to take a CXX bridge file, and manually generate the glue code.&lt;/p&gt;&lt;p data-block-key=&quot;begjh&quot;&gt;For Cargo builds, CXX recommends &lt;code&gt;cxx-build&lt;/code&gt; to obtain a CC builder, and the Zngur crate offers a builder struct to provide a similar CC interface, for building the glue code. Despite being harder to set up than the command line system, this offers deep configuration for more advanced use cases and could even allow combining Zngur with CXX. Corrosion also has experimental helpers for CXX builds with CMake (but there are no blockers on Zngur being supported here too in the future). Using a makefile or justfile to invoke build commands can also simplify the build process.&lt;/p&gt;&lt;p data-block-key=&quot;1pqlk&quot;&gt;An example &lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/zngur-example/build.rs&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Zngur build script&lt;/a&gt; for a simple project might look like this:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;use zngur::Zngur;

fn main() {
    build::rerun_if_changed(&amp;quot;main.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;prelude.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;trait_objects.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;nested_types.zng&amp;quot;);
    build::rerun_if_changed(&amp;quot;main.cpp&amp;quot;);
    build::rerun_if_changed(&amp;quot;nested_types.rs&amp;quot;);
    build::rerun_if_changed(&amp;quot;trait_objects.rs&amp;quot;);

    let crate_dir = build::cargo_manifest_dir();

    // Generate glue including the header, implementations (generated.cpp) and Rust code.
    Zngur::from_zng_file(crate_dir.join(&amp;quot;main.zng&amp;quot;))
        .with_cpp_file(crate_dir.join(&amp;quot;generated.cpp&amp;quot;))
        .with_h_file(crate_dir.join(&amp;quot;generated.h&amp;quot;))
        .with_rs_file(crate_dir.join(&amp;quot;./src/generated.rs&amp;quot;))
        .generate();

    let my_build = &amp;amp;mut cc::Build::new();
    let my_build = my_build.cpp(true).std(&amp;quot;c++17&amp;quot;);
    let my_build = || my_build.clone();

    // Build the C++ code using the CC builder, including the entrypoint to the program, and the generated impls
    my_build().file(&amp;quot;generated.cpp&amp;quot;).compile(&amp;quot;generated&amp;quot;);
    my_build().file(&amp;quot;main.cpp&amp;quot;).compile(&amp;quot;main&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;In CXX a &lt;a href=&quot;https://github.com/KDABLabs/blogs-rust/blob/main/zngur-cxx-comparison/cxx-example/build.rs&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;build script&lt;/a&gt; looks very similar, since they both use the CC builder interface:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;fn main() {
    cxx_build::bridge(&amp;quot;src/main.rs&amp;quot;)
        .file(&amp;quot;src/example.cc&amp;quot;)
        .compile(&amp;quot;cxx-example&amp;quot;);

    println!(&amp;quot;cargo:rerun-if-changed=src/example.cc&amp;quot;);
    println!(&amp;quot;cargo:rerun-if-changed=include/example.h&amp;quot;);
    println!(&amp;quot;cargo:rerun-if-changed=include/media.h&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;conclusion&quot; data-block-key=&quot;y9j0d&quot;&gt;Conclusion&lt;/h2&gt;&lt;p data-block-key=&quot;4p9dm&quot;&gt;As it stands at the minute, CXX definitely has stronger documentation, examples, and adoption, but remains to have strict rules around what gets added, and slow maintenance. Zngur offers a few benefits, but lacks key documentation, references of supported items, or even syntax. It does pose some interesting ideas which could be adopted by CXX, however, such as trait objects, and tagged unions (Rust enums which contain data, for example Option and Result). Although Zngur may be more time-consuming to write due to repeated definitions, we provide a custom prelude which you can place in your project, with any necessary basic types you may want, and this also includes a tool to generate any combination of these that you may want, see our tool &lt;a href=&quot;https://github.com/KDABLabs/zngur-prelude&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;zngur-prelude&lt;/a&gt; for more.&lt;/p&gt;&lt;p data-block-key=&quot;eg1do&quot;&gt;Some key differences in what is supported are laid out below:&lt;/p&gt;&lt;/div&gt;


&lt;table&gt;
    
    
        &lt;thead&gt;
            &lt;tr&gt;
                
                    
                        
                        
                            &lt;th scope=&quot;col&quot;  &gt;
                                
                                    
                                        Feature
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope=&quot;col&quot;  &gt;
                                
                                    
                                        CXX
                                    
                                
                            &lt;/th&gt;
                        
                    
                
                    
                        
                        
                            &lt;th scope=&quot;col&quot;  &gt;
                                
                                    
                                        Zngur
                                    
                                
                            &lt;/th&gt;
                        
                    
                
            &lt;/tr&gt;
        &lt;/thead&gt;
    
    &lt;tbody&gt;
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Generic Support
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Limited to built in types (listed below) when trying to define new generic types, e.g. no support for HashMap or Vec&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt; without a newtype wrapper.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Very broad support for defining Vec&amp;lt;Vec&amp;lt;T&amp;gt;&amp;gt;, HashMap&amp;lt;K, V&amp;gt;, Arc&amp;lt;dyn Trait&amp;gt;, with the caveat that each specialization needs to be defined manually.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Built In Support
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                CXX has built in support for Vec, String, UniquePtr, &amp;amp;[T] and a few others, and has strong guarantees about them.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Very limited built in support, not even supporting String or bool out of the box, but has very broad support for specifying these types yourself.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Trait Objects
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                No direct support for Box&amp;lt;dyn Trait&amp;gt;, Docs recommend using UniquePtr instead
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Full support: C++ types can implement Rust traits, and trait objects can be passed over the boundary.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Async Support
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Partial via cxx-async; integrates with Rust Future including futures crate.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                None yet. Can only emulate async via passing boxed function pointers and via channels.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Thread Safety
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Enforces Send and Sync requirements via static assertions.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                No assertions, but Mutex, Arc are supported.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Build System
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Integrated via cxx_build crate to support Cargo, CMake, and Bazel builds. Also has the cxxbridge tool to generate glue code from a file
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                CLI tool to generate glue code (zngur g file.zng) then manual build. Build scripts are supported but less so, with lesser adoption.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Documentation Status
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Mature, comprehensive docs at cxx.rs.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Sparse and incomplete, examples can be found in GitHub but they are limited.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Adoption
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Widely used, including in large projects like Chromium and Android.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Early adoption, Adobe seems to have taken an interest.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Overhead
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Zero-overhead abstraction, no serialization or copying.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Slight overhead possible; prioritizes flexibility and expressiveness.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Language Definition
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Inline within #[cxx::bridge] macro in the main Rust file.
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Specified in an IDL file (.zng).
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
            
                &lt;tr&gt;
                    
                        
                            
                            
                                
                                    &lt;th scope=&quot;row&quot;  &gt;
                                        
                                            
                                                Best Use
                                            
                                        
                                    &lt;/th&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Stable, performant FFI, integration with CXX-Qt, projects with simple types at the boundary
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                        
                            
                            
                                
                                    &lt;td  &gt;
                                        
                                            
                                                Research, quick prototyping, or projects making strong use of Traits and dynamic dispatch in Rust. Easier to integrate into an existing C++ project
                                            
                                        
                                    &lt;/td&gt;
                                
                            
                        
                    
                &lt;/tr&gt;
            
        
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;oqsck&quot;&gt;Choose CXX if your team needs proven safety, documentation, and tooling integration. Choose Zngur if you’re exploring advanced polymorphism or container-heavy data flows and are comfortable managing ABI stability yourself.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/weighing-up-zngur-and-cxx-for-rustc-interop/&quot;&gt;Weighing up Zngur and CXX for Rust/C++ Interop&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>c++</category><category>labs</category><category>open source</category><category>rust</category><category>tools</category></item><item><title>Automating Repetitive GUI Interactions in Embedded Development with Spix</title><link>https://www.kdab.com/automating-repetitive-gui-interactions-in-embedded-development-with-spix/</link><guid isPermaLink="true">https://www.kdab.com/automating-repetitive-gui-interactions-in-embedded-development-with-spix/</guid><description>&lt;p data-block-key=&quot;k9ick&quot;&gt;This blog post showcases Spix, a small but useful library for automating GUI-interaction in your Qt/QML-based applications. Just sending clicks or entering text to checking properties, Spix offers basic automated interaction. Combining the automated screenshot function with computer vision, you can even perform simple optical checks with Spix.&lt;/p&gt;</description><pubDate>Thu, 19 Feb 2026 08:18:12 GMT</pubDate><content:encoded>&lt;h1&gt;Automating Repetitive GUI Interactions in Embedded Development with Spix&lt;/h1&gt;
&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot;&gt;
        &lt;div class=&quot;image-variable-size-image&quot;&gt;
            &lt;img src=&quot;https://www.kdab.com/documents/2023-07-05-18-08-38-small_1.gif&quot; alt=&quot;2023-07-05-18-08-38-small_Blog_Christoph_Spix&quot;&gt;
        &lt;/div&gt;

        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;r7hie&quot;&gt;As Embedded Software Developers, we all know the pain: you make a code change, rebuild your project, restart the application - and then spend precious seconds repeating the same five clicks just to reach the screen you want to test. Add a login dialog on top of it, and suddenly those seconds turn into minutes. Multiply that by a hundred iterations per day, and it’s clear: this workflow is frustrating, error-prone, and a waste of valuable development time.&lt;/p&gt;&lt;p data-block-key=&quot;5kds4&quot;&gt;In this article, we’ll look at how to automate these repetitive steps using &lt;a href=&quot;https://github.com/faaxm/spix&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Spix&lt;/a&gt;, an open-source tool for GUI automation in Qt/QML applications. We’ll cover setup, usage scenarios, and how Spix can be integrated into your workflow to save hours of clicking, typing, and waiting.&lt;/p&gt;&lt;h2 id=&quot;the-problem:-click-fatigue-in-gui-testing&quot; data-block-key=&quot;ght5m&quot;&gt;The Problem: Click Fatigue in GUI Testing&lt;/h2&gt;&lt;p data-block-key=&quot;djqar&quot;&gt;Imagine this:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;1tiuj&quot;&gt;You start your application.&lt;/li&gt;&lt;li data-block-key=&quot;4ths2&quot;&gt;The login screen appears.&lt;/li&gt;&lt;li data-block-key=&quot;dii9m&quot;&gt;You enter your username and password.&lt;/li&gt;&lt;li data-block-key=&quot;d80kp&quot;&gt;You click &quot;Login&quot;.&lt;/li&gt;&lt;li data-block-key=&quot;78ntm&quot;&gt;Only then do you finally reach the UI where you can verify whether your code changes worked.&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;9hpm3&quot;&gt;This is fine the first few times - but if you’re doing it 100+ times a day, it becomes a serious bottleneck. While features like &lt;b&gt;hot reload&lt;/b&gt; can help in some cases, they aren’t always applicable - especially when structural changes are involved or when you must work with &quot;real&quot; production data.&lt;/p&gt;&lt;p data-block-key=&quot;1mabg&quot;&gt;So, what’s the alternative?&lt;/p&gt;&lt;h2 id=&quot;the-solution:-automating-gui-input-with-spix&quot; data-block-key=&quot;3ymr9&quot;&gt;The Solution: Automating GUI Input with Spix&lt;/h2&gt;&lt;p data-block-key=&quot;5e5pv&quot;&gt;&lt;a href=&quot;https://github.com/faaxm/spix&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Spix&lt;/a&gt; allows you to control your Qt/QML applications programmatically. Using scripts (typically Python), you can automatically:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;76u3q&quot;&gt;Insert text into input fields&lt;/li&gt;&lt;li data-block-key=&quot;eajkm&quot;&gt;Click buttons&lt;/li&gt;&lt;li data-block-key=&quot;699mb&quot;&gt;Wait for UI elements to appear&lt;/li&gt;&lt;li data-block-key=&quot;c7j6r&quot;&gt;Take and compare screenshots&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;e3mi6&quot;&gt;This means you can automate login steps, set up UI states consistently, and even extend your CI pipeline with &lt;b&gt;visual testing&lt;/b&gt;. Unlike manual hot reload tweaks or hardcoding start screens, Spix provides an &lt;b&gt;external, scriptable solution&lt;/b&gt; without altering your application logic.&lt;/p&gt;&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;setting-up-spix-in-your-project&quot; data-block-key=&quot;awzjs&quot;&gt;Setting up Spix in Your Project&lt;/h2&gt;&lt;p data-block-key=&quot;bu5nk&quot;&gt;Getting Spix integrated requires a few straightforward steps:&lt;/p&gt;&lt;h3 id=&quot;1.-add-spix-as-a-dependency&quot; data-block-key=&quot;pp4qw&quot;&gt;1. &lt;b&gt;Add Spix as a dependency&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;cs1gu&quot;&gt;Typically done via a Git submodule into your project’s third-party folder.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-bash  line-numbers &quot;&gt;git submodule add 3rdparty/spix git@github.com:faaxm/spix.git&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;2.-register-spix-in-cmake&quot; data-block-key=&quot;swc4s&quot;&gt;2.&lt;b&gt; Register Spix in CMake&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;78qpm&quot;&gt;Update your &lt;code&gt;CMakeLists.txt&lt;/code&gt; with a &lt;code&gt;find_package(Spix REQUIRED)&lt;/code&gt; call.&lt;/li&gt;&lt;li data-block-key=&quot;5ec9b&quot;&gt;Because of CMake quirks, you may also need to manually specify the path to Spix’s CMake modules.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cmake  line-numbers &quot;&gt;LIST(APPEND CMAKE_MODULE_PATH /home/christoph/KDAB/spix/cmake/modules)
find_package(Spix REQUIRED)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;3.-link-against-spix&quot; data-block-key=&quot;m3xad&quot;&gt;3.&lt;b&gt; Link against Spix&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;7cv8c&quot;&gt;Add &lt;code&gt;Spix&lt;/code&gt; to your &lt;code&gt;target_link_libraries&lt;/code&gt; call.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cmake  line-numbers &quot;&gt;target_link_libraries(myApp
  PRIVATE Qt6::Core
          Qt6::Quick 
          Qt6::SerialPort 
          Spix::Spix
)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;4.-initialize-spix-in-your-application&quot; data-block-key=&quot;odvmk&quot;&gt;4.&lt;b&gt; Initialize Spix in your application&lt;/b&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;1q365&quot;&gt;Include Spix headers in &lt;code&gt;main.cpp&lt;/code&gt;.&lt;/li&gt;&lt;li data-block-key=&quot;d95bc&quot;&gt;Add some lines of boilerplate code:&lt;ul&gt;&lt;li data-block-key=&quot;2ljlr&quot;&gt;Include the 2 Spix Headers (AnyRPCServer for Communication and QtQmlBot)&lt;/li&gt;&lt;li data-block-key=&quot;b2ora&quot;&gt;Start the Spix RPC server.&lt;/li&gt;&lt;li data-block-key=&quot;d3th0&quot;&gt;Create a &lt;code&gt;Spix::QtQmlBot&lt;/code&gt;.&lt;/li&gt;&lt;li data-block-key=&quot;7rom3&quot;&gt;Run the test server on a specified port (e.g. &lt;code&gt;9000&lt;/code&gt;).&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;#include &amp;lt;Spix/AnyRpcServer.h&amp;gt;
#include &amp;lt;Spix/QtQmlBot.h&amp;gt;
[...]

//Start the actual Runner/Server
spix::AnyRpcServer server;
auto bot = new spix::QtQmlBot();
bot-&amp;gt;runTestServer(server);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;idubt&quot;&gt;At this point, your application is &quot;Spix-enabled&quot;. You can verify this by checking for the open port (e.g. &lt;code&gt;localhost:9000&lt;/code&gt;).&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;or7ol&quot;&gt;Spix can be a Security Risk: Make sure to not expose Spix in any production environment, maybe only enable it for your Debug-builds.&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;where-spix-shines&quot; data-block-key=&quot;c0rsv&quot;&gt;Where Spix Shines&lt;/h2&gt;&lt;p data-block-key=&quot;5fkof&quot;&gt;Once the setup is done, Spix can be used to automate repetitive tasks. Let’s look at two particularly useful examples:&lt;/p&gt;&lt;h3 id=&quot;1.-automating-logins-with-a-python-script&quot; data-block-key=&quot;0n0mj&quot;&gt;1. Automating Logins with a Python Script&lt;/h3&gt;&lt;p data-block-key=&quot;38fq4&quot;&gt;Instead of typing your credentials and clicking &quot;Login&quot; manually, you can write a simple Python script that:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;fvros&quot;&gt;Connects to the Spix server on &lt;code&gt;localhost:9000&lt;/code&gt;&lt;/li&gt;&lt;li data-block-key=&quot;f286n&quot;&gt;Inputs text into the &lt;code&gt;userField&lt;/code&gt; and &lt;code&gt;passwordField&lt;/code&gt;&lt;/li&gt;&lt;li data-block-key=&quot;9ft5u&quot;&gt;Clicks the &quot;Login&quot; button (Items marked with &quot;Quotes&quot; are literal That-Specific-Text-Identifiers for Spix)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;import xmlrpc.client

session = xmlrpc.client.ServerProxy(&amp;#x27;http://localhost:9000&amp;#x27;)

session.inputText(&amp;#x27;mainWindow/userField&amp;#x27;, &amp;#x27;christoph&amp;#x27;)
session.inputText(&amp;#x27;mainWindow/passwordField&amp;#x27;, &amp;#x27;secret&amp;#x27;) 
session.mouseClick(&amp;#x27;mainWindow/&amp;quot;Login&amp;quot;&amp;#x27;)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;When executed, this script takes care of the entire login flow - no typing, no clicking, no wasted time. Better yet, you can check the script into your repository, so your whole team can reuse it.&lt;/p&gt;&lt;p data-block-key=&quot;f3qad&quot;&gt;For Development, Integration in Qt-Creator can be achieved with a Custom startup executable, that also starts this python script.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;yoeyx&quot;&gt;In a CI environment, this approach is particularly powerful, since you can ensure every test run starts from a clean state without relying on manual navigation.&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;2.-screenshot-comparison&quot; data-block-key=&quot;fzpkt&quot;&gt;2. Screenshot Comparison&lt;/h3&gt;&lt;p data-block-key=&quot;bf9dk&quot;&gt;Beyond input automation, Spix also supports &lt;b&gt;taking screenshots&lt;/b&gt;. Combined with Python libraries like OpenCV or &lt;code&gt;scikit-image&lt;/code&gt;, this opens up interesting possibilities for testing.&lt;/p&gt;&lt;h4 id=&quot;example-1:-full-screen-comparison&quot; data-block-key=&quot;ovfo0&quot;&gt;Example 1: Full-screen comparison&lt;/h4&gt;&lt;p data-block-key=&quot;4n3v3&quot;&gt;Take a screenshot of the main window and store it first:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;import xmlrpc.client

session = xmlrpc.client.ServerProxy(&amp;#x27;http://localhost:9000&amp;#x27;)

[...]
session.takeScreenshot(&amp;#x27;mainWindow&amp;#x27;, &amp;#x27;/tmp/screenshot.png&amp;#x27;)k&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;Now we can compare it with a reference image:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;from skimage import io
from skimage.metrics import structural_similarity as ssim

screenshot1 = io.imread(&amp;#x27;/tmp/reference.png&amp;#x27;, as_gray=True)
screenshot2 = io.imread(&amp;#x27;/tmp/screenshot.png&amp;#x27;, as_gray=True)

ssim_index = ssim(screenshot1, screenshot2, data_range=screenshot1.max() - screenshot1.min())

threshold = 0.95

if ssim_index == 1.0: 
    print(&amp;quot;The screenshots are a perfect match&amp;quot;)
elif ssim_index &amp;gt;= threshold:
    print(&amp;quot;The screenshots are similar, similarity: &amp;quot; + str(ssim_index * 100) + &amp;quot;%&amp;quot;)
else:
    print(&amp;quot;The screenshots are not similar at all, similarity: &amp;quot; + str(ssim_index * 100) + &amp;quot;%&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;This is useful for catching unexpected regressions in visual layout.&lt;/p&gt;&lt;h4 id=&quot;example-2:-finding-differences-in-the-same-ui&quot; data-block-key=&quot;0zrg1&quot;&gt;Example 2: Finding differences in the same UI&lt;/h4&gt;&lt;p data-block-key=&quot;fsbra&quot;&gt;Use OpenCV to highlight pixel-level differences between two screenshots—for instance, missing or misaligned elements:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-python  line-numbers &quot;&gt;import cv2

image1 = cv2.imread(&amp;#x27;/tmp/reference.png&amp;#x27;)
image2 = cv2.imread(&amp;#x27;/tmp/screenshot.png&amp;#x27;)

diff = cv2.absdiff(image1, image2)

# Convert the difference image to grayscale
gray = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)

# Threshold the grayscale image to get a binary image
_, thresh = cv2.threshold(gray, 30, 255, cv2.THRESH_BINARY)

contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(image1, contours, -1, (0, 0, 255), 2)

cv2.imshow(&amp;#x27;Difference Image&amp;#x27;, image1)
cv2.waitKey(0)&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;6qw4v&quot;&gt;This form of &lt;b&gt;visual regression testing&lt;/b&gt; can be integrated into your CI system. If the UI changes unintentionally, Spix can detect it and trigger an alert.&lt;/p&gt;&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;1024-637_Blog_Christoph_Spix&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/1024-637_1.original.png&quot; class=&quot;1024-637_Blog_Christoph_Spix&quot; alt=&quot;1024-637_Blog_Christoph_Spix&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;2759c&quot;&gt;Defective Image&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;1024-639_Blog_Christoph_Spix&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/1024-639_1.original.png&quot; class=&quot;1024-639_Blog_Christoph_Spix&quot; alt=&quot;1024-639_Blog_Christoph_Spix&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-center&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;2759c&quot;&gt;The script marked the defective parts of the image compared to the should-be image.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;recap&quot; data-block-key=&quot;j3bi4&quot;&gt;Recap&lt;/h2&gt;&lt;p data-block-key=&quot;398cv&quot;&gt;&lt;a href=&quot;https://github.com/faaxm/spix&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Spix&lt;/a&gt; is not a full-blown GUI testing framework like Squish, but it fills a useful niche for embedded developers who want to:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;30u8&quot;&gt;Save time on repetitive input (like logins).&lt;/li&gt;&lt;li data-block-key=&quot;2l6p7&quot;&gt;Share reproducible setup scripts with colleagues.&lt;/li&gt;&lt;li data-block-key=&quot;ba5ar&quot;&gt;Perform lightweight visual regression testing in CI.&lt;/li&gt;&lt;li data-block-key=&quot;3s1sr&quot;&gt;Interact with their applications on embedded devices remotely.&lt;/li&gt;&lt;/ul&gt;&lt;p data-block-key=&quot;9as1q&quot;&gt;While there are limitations (e.g. manual wait times, lack of deep synchronization with UI states), Spix provides a powerful and flexible way to automate everyday development tasks - without having to alter your application logic.&lt;/p&gt;&lt;p data-block-key=&quot;8pqgh&quot;&gt;If you’re tired of clicking the same buttons all day, give Spix a try. It might just save you hours of time and frustration in your embedded development workflow.&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/WTYl4wHL0NI?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;GUI Automation and Testing with Spix&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;


&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/automating-repetitive-gui-interactions-in-embedded-development-with-spix/&quot;&gt;Automating Repetitive GUI Interactions in Embedded Development with Spix&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>python</category><category>qt</category><category>tools</category></item><item><title>KDAB at Embedded World 2026, Nuremberg, Germany</title><link>https://www.kdab.com/kdab-at-embedded-world-2026-nuremberg-germany/</link><guid isPermaLink="true">https://www.kdab.com/kdab-at-embedded-world-2026-nuremberg-germany/</guid><description>&lt;p data-block-key=&quot;s1l6s&quot;&gt;KDAB exhibited at &lt;b&gt;Embedded World&lt;/b&gt; from &lt;b&gt;March 10th through 12th, 2026&lt;/b&gt;, in Nuremberg, Germany.&lt;/p&gt;</description><pubDate>Tue, 17 Feb 2026 08:08:00 GMT</pubDate><content:encoded>&lt;h1&gt;KDAB at Embedded World 2026, Nuremberg, Germany&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;p828o&quot;&gt;At &lt;a href=&quot;https://www.embedded-world.de/en&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;Embedded World 2026&lt;/b&gt;&lt;/a&gt;, KDAB showcased how we help customers build robust, high-performance embedded software using &lt;b&gt;Qt, C++, Rust, Slint, and Flutter&lt;/b&gt;. From multi-display streaming and real-time 3D UIs to developer tooling and continuous integration on real hardware, our booth featured hands-on demos that reflect the challenges of embedded systems.&lt;/p&gt;&lt;p data-block-key=&quot;9c5qi&quot;&gt;Visitors stopped by our booth 4-302 to experience the demos live and to speak with our engineers about their projects.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;31ry2&quot;&gt;📍 Nuremberg, Germany&lt;br/&gt;📅 March 10–12, 2026&lt;br/&gt;📍 KDAB Booth: 4-302&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;migration-and-modernization-services&quot; data-block-key=&quot;9s44n&quot;&gt;Migration and Modernization Services&lt;/h2&gt;&lt;p data-block-key=&quot;4v3r0&quot;&gt;KDAB helps customers transition legacy systems - whether that means moving from &lt;b&gt;Windows CE to Embedded Linux&lt;/b&gt; or &lt;b&gt;upgrading an existing software stack&lt;/b&gt;. This includes advanced code migration and tooling, as well as setting up complete embedded Linux environments with technologies such as &lt;b&gt;Yocto&lt;/b&gt; or &lt;b&gt;Torizon&lt;/b&gt;, tailored to the target hardware.&lt;/p&gt;&lt;p data-block-key=&quot;a3ga4&quot;&gt;For teams planning to move from Windows CE, there is a guide on migrating to Embedded Linux, outlining key challenges, architecture considerations, and best‑practice workflows in detail. &lt;a href=&quot;https://www.kdab.com/windowsce-to-embedded-linux-migration/&quot;&gt;Read it here&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;25tiv&quot;&gt;Beyond Windows Embedded migrations, KDAB offers expertise in a wide range of modernization projects, including &lt;a href=&quot;https://www.kdab.com/services/qt-services/qt-5-to-qt-6-migration-services/&quot;&gt;Qt 5 to Qt 6 migrations&lt;/a&gt;, &lt;a href=&quot;https://www.kdab.com/services/software-consulting/legacy-framework-migration/&quot;&gt;legacy framework transitions&lt;/a&gt;, and broader codebase and platform modernization efforts.&lt;/p&gt;&lt;h2 id=&quot;rugged-controller-for-arx-gereon-rcs&quot; data-block-key=&quot;q30uz&quot;&gt;Rugged Controller for ARX Gereon RCS&lt;/h2&gt;&lt;h3 id=&quot;kdab-designed-and-built-a-ui-for-robotic-platform-and-payload-control&quot; data-block-key=&quot;nfp3t&quot;&gt;KDAB Designed and Built a UI for Robotic Platform &amp;amp; Payload Control&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;5n24a&quot;&gt;UI built using Qt 6 and QML&lt;/li&gt;&lt;li data-block-key=&quot;1gsi0&quot;&gt;GStreamer for camera video playback&lt;/li&gt;&lt;li data-block-key=&quot;ctd1t&quot;&gt;Controller &amp;lt;-&amp;gt; Robot communication over multiple networks&lt;/li&gt;&lt;li data-block-key=&quot;6r3fn&quot;&gt;Oﬄine autonomous mapping support&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-33 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://www.arx-robotics.com/&quot; title=&quot;Logos_ARX&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_ARX&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_ARX.original.png&quot; class=&quot;Logos_ARX&quot; alt=&quot;Logos_ARX&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;live-3d-ui-for-autonomous-public-transport&quot; data-block-key=&quot;61itv&quot;&gt;Live 3D UI for Autonomous Public Transport&lt;/h2&gt;&lt;ul&gt;&lt;li data-block-key=&quot;7f51k&quot;&gt;Autonomous bus driven by Motor AI infrastructure&lt;/li&gt;&lt;li data-block-key=&quot;7m52i&quot;&gt;Interactive 3D dashboard&lt;/li&gt;&lt;li data-block-key=&quot;113m&quot;&gt;Real-time data streamed via MQTT&lt;/li&gt;&lt;li data-block-key=&quot;49urg&quot;&gt;Touch interface built with Slint&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://www.motor-ai.com/&quot; title=&quot;Logos_MotorAI&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_MotorAI&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_MotorAI.original.png&quot; class=&quot;Logos_MotorAI&quot; alt=&quot;Logos_MotorAI&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://slint.dev/&quot; title=&quot;Logos_Slint&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_Slint&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_Slint.original.png&quot; class=&quot;Logos_Slint&quot; alt=&quot;Logos_Slint&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;qt-gstreamer-multi-display-demo&quot; data-block-key=&quot;gpv2d&quot;&gt;Qt GStreamer Multi-Display Demo&lt;/h2&gt;&lt;h3 id=&quot;stream-qt-applications-to-multiple-browser-instances&quot; data-block-key=&quot;k4x4k&quot;&gt;Stream Qt Applications to Multiple Browser Instances&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;8mjae&quot;&gt;Standard Qt/QML Application on an Intel Atom-based CPU&lt;/li&gt;&lt;li data-block-key=&quot;9erec&quot;&gt;Complex GStreamer pipeline to transform into a WebRTC stream&lt;/li&gt;&lt;li data-block-key=&quot;br582&quot;&gt;Improved the GStreamer plugin&lt;/li&gt;&lt;li data-block-key=&quot;2mk57&quot;&gt;Results viewable in any WebRTC-capable browser&lt;/li&gt;&lt;li data-block-key=&quot;3ebd3&quot;&gt;Full touch input and interactivity across multiple screens&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-33 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://www.qt.io/&quot; title=&quot;Logos_BuiltQt&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_BuiltQt&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_BuiltQt_dhgNqiu.original.png&quot; class=&quot;Logos_BuiltQt&quot; alt=&quot;Logos_BuiltQt&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;devicelab-for-embedded-hardware&quot; data-block-key=&quot;87cti&quot;&gt;DeviceLab for Embedded Hardware&lt;/h2&gt;&lt;h3 id=&quot;continuous-integration-system-on-real-devices&quot; data-block-key=&quot;2qo6n&quot;&gt;Continuous Integration System on Real Devices&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;80r8p&quot;&gt;DeviceLab allows for testing Flutter applications on various embedded boards&lt;/li&gt;&lt;li data-block-key=&quot;99eam&quot;&gt;The Flutter developer experience on embedded is falling short at the moment&lt;/li&gt;&lt;li data-block-key=&quot;aj40a&quot;&gt;To improve the experience, it is necessary to start testing Flutter on embedded hardware&lt;/li&gt;&lt;li data-block-key=&quot;aqn1u&quot;&gt;A big improvement would be to integrate some of the most common embedded platforms into the official Flutter DeviceLab&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://flutter.dev/&quot; title=&quot;Logos_Flutter&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_Flutter&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_Flutter_3o7mIJr.original.png&quot; class=&quot;Logos_Flutter&quot; alt=&quot;Logos_Flutter&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;



&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-50 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                    &lt;a href=&quot;https://www.industrialflutter.com/&quot; title=&quot;Logos_IF&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                &lt;img id=&quot;Logos_IF&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_IF.original.png&quot; class=&quot;Logos_IF&quot; alt=&quot;Logos_IF&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;cxx-qt-safe-rust-bindings-for-qt&quot; data-block-key=&quot;3fp0q&quot;&gt;CXX-Qt - Safe Rust Bindings for Qt&lt;/h2&gt;&lt;h3 id=&quot;integration-for-c++-and-rust-applications&quot; data-block-key=&quot;zkukn&quot;&gt;Integration for C++ and Rust applications&lt;/h3&gt;&lt;p data-block-key=&quot;epkcs&quot;&gt;KDAB supports and maintains &lt;a href=&quot;https://github.com/KDAB/cxx-qt&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CXX-Qt&lt;/a&gt;. A set of Rust crates for creating bidirectional Rust ⇄ C++ bindings with Qt. It can be used to integrate Rust into C++ applications via CMake, or to build Rust applications with Cargo.&lt;/p&gt;&lt;p data-block-key=&quot;2tdvt&quot;&gt;Watch our YouTube series &lt;a href=&quot;https://www.youtube.com/playlist?list=PL6CJYn40gN6jOg_cPqRfXMNriHknKy4VW&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&quot;Mixing C++ and Rust&quot;&lt;/a&gt; to learn more.&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;3ame5&quot;&gt;Enables Rust and C++ ecosystems to be used in the same application&lt;/li&gt;&lt;li data-block-key=&quot;2g8vu&quot;&gt;Allows for idiomatic Rust and C++ code&lt;/li&gt;&lt;li data-block-key=&quot;8l2o3&quot;&gt;Integrates easily into existing applications&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-25 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://rust-lang.org/&quot; title=&quot;Logos_Rust&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Logos_Rust&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Logos_Rust.original.png&quot; class=&quot;Logos_Rust&quot; alt=&quot;Logos_Rust&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;developer-tools-for-qt-c++-and-linux&quot; data-block-key=&quot;ctkvx&quot;&gt;Developer Tools for Qt, C++, and Linux&lt;/h2&gt;&lt;h3 id=&quot;performance-optimization-tools&quot; data-block-key=&quot;vw6z8&quot;&gt;Performance Optimization Tools&lt;/h3&gt;&lt;p data-block-key=&quot;ba833&quot;&gt;A selection of useful developer tools for debugging and profiling&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;cnj96&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/gammaray/&quot;&gt;GammaRay&lt;/a&gt;: High-level introspection tool for Qt applications&lt;/li&gt;&lt;li data-block-key=&quot;4jocq&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/kddockwidgets/&quot;&gt;KDDockWidgets&lt;/a&gt;: KDAB&apos;s Dock Widget Framework for Qt&lt;/li&gt;&lt;li data-block-key=&quot;1e4n&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/hotspot/&quot;&gt;Hotspot&lt;/a&gt;: The Linux perf GUI for performance analysis&lt;/li&gt;&lt;li data-block-key=&quot;dul2b&quot;&gt;&lt;a href=&quot;https://www.kdab.com/clazy-video/&quot;&gt;Clazy Static Code Analyzer&lt;/a&gt;: LLVM/Clang-based static analyzer for Qt&lt;/li&gt;&lt;li data-block-key=&quot;4qtfk&quot;&gt;&lt;a href=&quot;https://github.com/KDE/heaptrack&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Heaptrack&lt;/a&gt;: Heap memory profiler and analysis GUI for Linux&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;videos-from-previous-embedded-worlds&quot; data-block-key=&quot;a77ye&quot;&gt;Recap video Embedded World 2026&lt;/h2&gt;&lt;p data-block-key=&quot;fftv9&quot;&gt;This 2-minute recap offers a quick look at the diverse range of customer-driven demos we featured at Embedded World 2026.&lt;/p&gt;&lt;/div&gt;







&lt;div class=&quot;cookieconsent-optin-marketing overlay-embed-block&quot;&gt;
    &lt;div style=&quot;padding-bottom: 56.49999999999999%;&quot; class=&quot;responsive-object&quot;&gt;
    &lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/W_BLf8NiX4E?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Embedded World 2026: KDAB Project &amp;amp; Demo Highlights&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;/div&gt;




&lt;style&gt;
.overlay-embed-block .responsive-object {
    position: relative;
}

.overlay-embed-block .responsive-object iframe,
.overlay-embed-block .responsive-object object,
.overlay-embed-block .responsive-object embed {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
&lt;/style&gt;


&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/kdab-at-embedded-world-2026-nuremberg-germany/&quot;&gt;KDAB at Embedded World 2026, Nuremberg, Germany&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator></item><item><title>MSVC - Debugging the Static Initialization Order</title><link>https://www.kdab.com/msvc-debugging-the-static-initialization-order/</link><guid isPermaLink="true">https://www.kdab.com/msvc-debugging-the-static-initialization-order/</guid><description>&lt;p data-block-key=&quot;1yf9k&quot;&gt;A bug which is &lt;b&gt;experienced by&lt;/b&gt; and also &lt;b&gt;caused by&lt;/b&gt; code running before main(). How do you deal with that? This article explains the underlying mechanics of how static initialization works, and one way to debug it.&lt;/p&gt;</description><pubDate>Thu, 18 Dec 2025 07:48:00 GMT</pubDate><content:encoded>&lt;h1&gt;MSVC - Debugging the Static Initialization Order&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;4jay6&quot;&gt;Have you ever encountered a bug which is &lt;b&gt;&lt;i&gt;experienced by&lt;/i&gt;&lt;/b&gt; and also &lt;b&gt;&lt;i&gt;caused by&lt;/i&gt;&lt;/b&gt; code running before main() even starts? This can happen if you have a static variable or singleton of a class. Each constructor of such classes gets called in order. But what order?&lt;/p&gt;&lt;p data-block-key=&quot;bar93&quot;&gt;Turns out, this order is undefined by design. And this actually has a name:&lt;br/&gt;&lt;a href=&quot;https://en.cppreference.com/w/cpp/language/siof.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;i&gt;Static Initialization Order Fiasco&lt;/i&gt;&lt;/a&gt;&lt;/p&gt;&lt;p data-block-key=&quot;18v5q&quot;&gt;This mentions code depending on other code. I certainly don&apos;t recommend ever intentionally designing an application with such dependencies. But... it can still happen. That&apos;s when this knowledge is useful.&lt;/p&gt;&lt;h2 id=&quot;how-the-initialization-works&quot; data-block-key=&quot;ihewx&quot;&gt;How the initialization works&lt;/h2&gt;&lt;p data-block-key=&quot;ainif&quot;&gt;When the program compiles and links, a table of function pointers to all the static methods which need to be called to initialize the static variables is created.&lt;br/&gt;Then, the MainCRTStartup function loops over these pointers and calls them. Again, all this happens before &lt;code&gt;main()&lt;/code&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;daqg8&quot;&gt;With this background info, we can be more specific in formulating the problem:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;al1pv&quot;&gt;One of the constructors of a static variable leaves behind its side effects which leads to code in another constructor crashing.&lt;/li&gt;&lt;li data-block-key=&quot;ccv9b&quot;&gt;We can see the outcome where its side effects cause problems in subsequent constructors/static methods.&lt;ul&gt;&lt;li data-block-key=&quot;fuq7&quot;&gt;But we don&apos;t know how many constructors were called before &quot;ours&quot;.&lt;/li&gt;&lt;li data-block-key=&quot;5c1pk&quot;&gt;We don&apos;t know which of those are causing it.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li data-block-key=&quot;26dbg&quot;&gt;We need to know this to limit the scope.&lt;/li&gt;&lt;li data-block-key=&quot;atibb&quot;&gt;The error must be somewhere in there.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;what-the-underlying-code-looks-like&quot; data-block-key=&quot;t3jtp&quot;&gt;What the underlying code looks like&lt;/h2&gt;&lt;p data-block-key=&quot;dgel8&quot;&gt;Wouldn&apos;t it be great if we could examine the &quot;MainCRTStartup&quot;?&lt;/p&gt;&lt;p data-block-key=&quot;enqbc&quot;&gt;Microsoft actually supplies source code for this! It can be found in the file &lt;code&gt;exe_common.inl&lt;/code&gt; which in my case was found at &lt;code&gt;&quot;C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.39.33519\crt\src\vcruntime\exe_common.inl&quot;&lt;/code&gt;&lt;/p&gt;&lt;p data-block-key=&quot;4u8eq&quot;&gt;The call to &lt;code&gt;_initterm&lt;/code&gt; performs this initialization (line 17):&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;bool has_cbool has_ctor = false;  
__try  
{  
    bool const is_nested = __scrt_acquire_startup_lock();  
  
    if (__scrt_current_native_startup_state == __scrt_native_startup_state::initializing)  
    {  
        __scrt_fastfail(FAST_FAIL_FATAL_APP_EXIT);  
    }  
    else if (__scrt_current_native_startup_state == __scrt_native_startup_state::uninitialized)  
    {  
        __scrt_current_native_startup_state = __scrt_native_startup_state::initializing;  
  
        if (_initterm_e(__xi_a, __xi_z) != 0)  
            return 255;  
  
        _initterm(__xc_a, __xc_z);  // &amp;lt;--- THIS LINE (256)!
  
        __scrt_current_native_startup_state = __scrt_native_startup_state::initialized;  
    }  
    else  
    {  
        has_cctor = true;  
    }  
  
    __scrt_release_startup_lock(is_nested);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;debugging-this-with-x64-debug&quot; data-block-key=&quot;35dgt&quot;&gt;Debugging this with &lt;a href=&quot;https://x64dbg.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;x64-debug&lt;/a&gt;&lt;/h2&gt;&lt;p data-block-key=&quot;bha98&quot;&gt;Depending on the debugger, this might be out of scope for your IDE. This was the case for me.&lt;/p&gt;&lt;h3 id=&quot;prerequisites&quot; data-block-key=&quot;1xmid&quot;&gt;Prerequisites&lt;/h3&gt;&lt;p data-block-key=&quot;dbeg0&quot;&gt;It&apos;s assumed you can either use a regular debug build or a release build with generated PDB file (&lt;code&gt;/Zi&lt;/code&gt; flag to generate separate PDB for MSVC compiler).&lt;/p&gt;&lt;p data-block-key=&quot;2n2b7&quot;&gt;Ensure entry breakpoint is set in the options dialog:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113016&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Pasted_image_20250505113016.original.png&quot; class=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113016&quot; alt=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113016&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;lw7jy&quot;&gt;This automatic breakpoint will pause the debugging at the program entry point - not main() but the actual entry point.&lt;/p&gt;&lt;h3 id=&quot;stepping-into-the-program&quot; data-block-key=&quot;dbxs0&quot;&gt;Stepping into the program&lt;/h3&gt;&lt;p data-block-key=&quot;6ak7a&quot;&gt;There is a lot to look at in this screenshot. The program is called &lt;code&gt;gltf_render_pbr&lt;/code&gt;. Use the &lt;b&gt;&lt;i&gt;step-into&lt;/i&gt;&lt;/b&gt; button in the debugger until you reach the correct &quot;file&quot; - it will tell you on the right hand side. Look at the very right for &lt;code&gt;exe_common.inl&lt;/code&gt;&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113502&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Pasted_image_20250505113502.original.png&quot; class=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113502&quot; alt=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113502&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;lw7jy&quot;&gt;Now you can find the correct line for the breakpoint. It is marked in red here. Also notice the &lt;code&gt;__xc_z&lt;/code&gt; and &lt;code&gt;__xc_a&lt;/code&gt;, those are the start and end pointers of the table where the static initializer function pointers are stored. Note the little red dot to the left of the red highlighted address? That means I have a breakpoint set on that instruction. The &lt;code&gt;call &amp;lt;gltf_render_pbr._initterm&amp;gt;&lt;/code&gt; instruction. This is the one jumping into the actual performing code inside &lt;code&gt;ucrtbased.dll&lt;/code&gt;.&lt;/p&gt;&lt;h3 id=&quot;ucrtbased.dll-loop&quot; data-block-key=&quot;8rf9f&quot;&gt;ucrtbased.dll loop&lt;/h3&gt;&lt;p data-block-key=&quot;dn0pc&quot;&gt;When you step into that, you will end up here:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                
                &lt;img id=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113859&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/Pasted_image_20250505113859.original.png&quot; class=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113859&quot; alt=&quot;Jonatan_Blog_MSVC_Pasted image 20250505113859&quot;&gt;
                
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;lw7jy&quot;&gt;This is the loop which calls each initializer in the list.&lt;/p&gt;&lt;p data-block-key=&quot;m48k&quot;&gt;The actual call into each initialization method is: &lt;code&gt;call qword ptr ds:[7FFCD4B6BBA0]&lt;/code&gt;.&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;ciiim&quot;&gt;Set a breakpoint there like I&apos;ve done in the screenshot above.&lt;/li&gt;&lt;li data-block-key=&quot;4vebv&quot;&gt;Now, from there, &lt;b&gt;&lt;i&gt;step into&lt;/i&gt;&lt;/b&gt; 2 times more to reach the actual code.&lt;/li&gt;&lt;li data-block-key=&quot;9g18g&quot;&gt;When you&apos;ve noted where you ended up, just press &lt;b&gt;run&lt;/b&gt; and you should get back to the breakpoint. It&apos;s inside the loop after all.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;rpy7t&quot;&gt;Note that the first static method the &quot;pre_cpp_initialization&quot; step in the CRT code, &lt;code&gt;exe_common.inl:216&lt;/code&gt;&lt;br/&gt; It initializes exception handlers and other things.&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;q02c7&quot;&gt;The next call should be into actual C++ initializers. If you have debug symbols, you should be able to see where you end up. In the example program I used - &lt;code&gt;fmt&lt;/code&gt; had a static method, and then the next after that was my test code.&lt;/p&gt;&lt;h3 id=&quot;when-debugging-the-program-next-time&quot; data-block-key=&quot;l7vmx&quot;&gt;When debugging the program next time&lt;/h3&gt;&lt;p data-block-key=&quot;7di64&quot;&gt;When you restart the program in the debugger, &lt;b&gt;each DLL&lt;/b&gt; will also have its own CRT startup sequence. Thus:&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;2m6l4&quot;&gt;disable the breakpoint inside the loop in ucrtbased.dll&lt;/li&gt;&lt;li data-block-key=&quot;dudhv&quot;&gt;run until the breakpoint for the &lt;code&gt;_initterm&lt;/code&gt; call&lt;/li&gt;&lt;li data-block-key=&quot;6peed&quot;&gt;re-enable the breakpoint inside the loop in ucrtbased.dll&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/msvc-debugging-the-static-initialization-order/&quot;&gt;MSVC - Debugging the Static Initialization Order&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>c++</category><category>desktop</category><category>windows</category></item><item><title>Static Assertions in Rust</title><link>https://www.kdab.com/static-assertions-in-rust/</link><guid isPermaLink="true">https://www.kdab.com/static-assertions-in-rust/</guid><description>&lt;p data-block-key=&quot;o00k7&quot;&gt;Rust doesn’t include a built-in equivalent to C++’s static_assert, but you can achieve similar compile-time checks with a simple macro. This allows you to enforce conditions during compilation without external dependencies. While the Rust standard library has opted not to include such functionality, it&apos;s easy to implement and integrate directly into your own projects.&lt;/p&gt;</description><pubDate>Thu, 20 Nov 2025 07:58:00 GMT</pubDate><content:encoded>&lt;h1&gt;Static Assertions in Rust&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;In C++, we have a useful way to ensure certain conditions are met during compilation. This is called &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/static_assert.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;static_assert&lt;/a&gt;. Here is an oversimplified example, which should always pass:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;constexpr int A = 6;

static_assert(A == 6);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;In Rust it&apos;s not obvious that we have an equivalent for &lt;code&gt;static_assert&lt;/code&gt; out of the box. Of course, we have the &lt;a href=&quot;https://doc.rust-lang.org/std/macro.assert.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;assert! macro&lt;/a&gt; but there&apos;s nothing built-in like a &lt;code&gt;static_assert!&lt;/code&gt; or the more fitting &lt;code&gt;const_assert!&lt;/code&gt; to use. However, with modern Rust, it’s easy to make an equivalent to use in your projects with a small macro.&lt;/p&gt;&lt;p data-block-key=&quot;3h5na&quot;&gt;The macro code is short and sweet, so let&apos;s begin by showing it first:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;macro_rules! const_assert {
    ($x:expr) =&amp;gt; {
        const _: () = ::core::assert!($x);
    };
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;If you haven&apos;t come across &lt;code&gt;const&lt;/code&gt; in Rust, it has a different meaning than in C++. You can read more &lt;a href=&quot;https://doc.rust-lang.org/std/keyword.const.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;about it here&lt;/a&gt; but the main difference is that it usually means &quot;compile-time&quot;, while in C++ it means &quot;immutable&quot; or &quot;constant&quot;. If the Rust compiler can&apos;t evaluate it at compile-time, it throws an error.&lt;/p&gt;&lt;p data-block-key=&quot;5dalv&quot;&gt;Now going back to the &lt;code&gt;macro_rules!&lt;/code&gt; part, let me explain this super simple example. First, we define a name for the macro - in this case &lt;code&gt;const_assert&lt;/code&gt;:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;macro_rules! const_assert&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;Then we want to define how the arguments are matched and parsed. These are called designators, and they are written in the form of &lt;code&gt;$name:type&lt;/code&gt;. So in our case, we are defining &lt;code&gt;$x&lt;/code&gt; with a type of &lt;code&gt;expr&lt;/code&gt; (short for expression.)&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;($x:expr) =&amp;gt; {&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;Now that we have an expression, we can substitute it in new code. For our case that&apos;s putting it in an &lt;code&gt;assert!&lt;/code&gt; but in a &lt;code&gt;const&lt;/code&gt; context:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const _: () = ::core::assert!($x);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;Macros are a huge topic on their own, and our example here is on the easier side. You can read more about how &lt;code&gt;macro_rules!&lt;/code&gt; can be used &lt;a href=&quot;https://doc.rust-lang.org/rust-by-example/macros.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt; if you&apos;re curious. If you want to test your skills, try modifying the macro to accept other forms of &lt;code&gt;assert!&lt;/code&gt;, e.g. to pass a custom error message.&lt;/p&gt;&lt;p data-block-key=&quot;98udq&quot;&gt;Let&apos;s move back to &lt;code&gt;const_assert!&lt;/code&gt;, here&apos;s the above example but written in Rust:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const A: i32 = 6;

const_assert!(A == 6);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;And it&apos;s roughly equivalent to writing this manually:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const A: i32 = 6;

const _: () = assert!(A == 6);&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;



&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;In my opinion, though, the intent isn&apos;t as clear in the non-macro version. The nice thing about the macro - and the main draw - is that it looks like an &lt;code&gt;assert!&lt;/code&gt; which is an existing language construct that you would already be familiar reading.&lt;/p&gt;&lt;p data-block-key=&quot;ev9gk&quot;&gt;And similar to &lt;code&gt;static_assert&lt;/code&gt; in C++, the macro can be put in the global scope and also in functions:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-rust  line-numbers &quot;&gt;const A: i32 = 6;

const B: i32 = 5;

const_assert!(B == 6);

fn main() {
    const_assert!(A == 6);

    println!(&amp;quot;{A}&amp;quot;);
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;68v3e&quot;&gt;I didn’t create this macro, I stumbled across it while researching static assertions to use in &lt;a href=&quot;https://github.com/KDAB/CXX-Qt&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;CXX-Qt&lt;/a&gt;. I was initially going to pick from one of the many choices of static assertion crates, until I looked at their source code and found a lot of them are identical to the macro I showed above. Since &lt;code&gt;macro_rules!&lt;/code&gt; are so easy to integrate, it made sense to vendor it instead of adding another dependency.&lt;/p&gt;&lt;p data-block-key=&quot;8ol30&quot;&gt;There was an issue brought forward to the Rust Library team to add something akin to C++&apos;s &lt;code&gt;static_assert&lt;/code&gt; into &lt;a href=&quot;https://github.com/rust-lang/libs-team/issues/325&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;the standard library&lt;/a&gt;. The thread goes over some of the limitations with the method shown here as well. Yet &lt;a href=&quot;https://github.com/rust-lang/libs-team/issues/325#issuecomment-2807186979&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;they ultimately decided&lt;/a&gt; that having an equivalent in the standard library isn&apos;t something they want. I&apos;m not sure if I agree with that decision, but, fortunately, it&apos;s easy to add your own.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/static-assertions-in-rust/&quot;&gt;Static Assertions in Rust&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>rust</category></item><item><title>Understanding Type-Based Alias Analysis in C and C++</title><link>https://www.kdab.com/understanding-type-based-alias-analysis-in-c-and-cpp/</link><guid isPermaLink="true">https://www.kdab.com/understanding-type-based-alias-analysis-in-c-and-cpp/</guid><description>&lt;p data-block-key=&quot;hon5z&quot;&gt;Type systems do more than just catch errors - they guide compiler optimizations too. This post explores type-based alias analysis in C and C++, showing how aliasing affects performance, why undefined behavior matters, and how the restrict keyword helps unlock faster code.&lt;/p&gt;</description><pubDate>Wed, 22 Oct 2025 10:31:00 GMT</pubDate><content:encoded>&lt;h1&gt;Understanding Type-Based Alias Analysis in C and C++&lt;/h1&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;what-are-type-systems&quot; data-block-key=&quot;e1mbz&quot;&gt;What are Type Systems?&lt;/h2&gt;&lt;p data-block-key=&quot;2d2rr&quot;&gt;Type system in statically typed language empowers compilers to identify and reject invalid programs during the type checking phase. Type information associated with different elements of the program (e.g. functions, variables) helps the compiler to detect the state of the program without actually executing the program. While programming language types are frequently employed to detect specific errors during compilation, what is interesting and important is that they serve other purposes as well.&lt;/p&gt;&lt;h2 id=&quot;let&amp;#x27;s-talk-about-type-based-alias-analysis&quot; data-block-key=&quot;sf2dk&quot;&gt;Let’s Talk about Type-based Alias Analysis&lt;/h2&gt;&lt;p data-block-key=&quot;2c8p8&quot;&gt;Type-based alias analysis is a technique that determines whether two or more pointers or references in a program can potentially point to the same memory address (alias each other, in other words). This analysis mainly relies on the concept of compatible types.&lt;/p&gt;&lt;p data-block-key=&quot;dbjao&quot;&gt;But what exactly are compatible types?&lt;/p&gt;&lt;p data-block-key=&quot;779ph&quot;&gt;So, aliasing typically occurs between compatible data types. To clarify, data types are deemed compatible when they differ only in attributes like being signed, unsigned, const, or volatile. For instance, both &quot;char&quot; and &quot;unsigned char&quot; are compatible with any other type.&lt;/p&gt;&lt;p data-block-key=&quot;8kkpg&quot;&gt;Let’s look at a simple example to understand better:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void modifyValues(int *a, short *b) {
  *a = 42;
  *b = 3;
  *a += 5;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;Assuming the function call is &lt;b&gt;modifyValues(&amp;amp;n, (short*)&amp;amp;n)&lt;/b&gt; here, &lt;b&gt;n&lt;/b&gt; might be an integer type.&lt;/p&gt;&lt;p data-block-key=&quot;710ne&quot;&gt;What would be the resulting value of n?&lt;/p&gt;&lt;p data-block-key=&quot;cc1nn&quot;&gt;It depends on the optimization level. Let’s look at the assembly in the case of no optimization level (O0) and its being compiled with clang.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;mov rax, qword ptr [rbp - 8]
mov dword ptr [rax], 42  ; *a = 42

mov rax, qword ptr [rbp - 16]
mov word ptr [rax], 3    ; *b = 3

mov rax, qword ptr [rbp - 8]
mov ecx, dword ptr [rax]
add ecx, 5               ; *a += 5;&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;This is pretty much standard, similar to what we wrote in high-level code - basically a one-to-one mapping. Looking at the assembly, it is clear that there is aliasing, a and b pointing to the exact same location. Hence, the final value for &lt;b&gt;n&lt;/b&gt; would be 8 in this case.&lt;/p&gt;&lt;p data-block-key=&quot;chfub&quot;&gt;Now, let’s compile the program using an optimization level -O2 ,&lt;/p&gt;&lt;p data-block-key=&quot;3c34f&quot;&gt;Take a look at this big assembly:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;mov word ptr [rsi], 3
mov dword ptr [rdi], 47&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;




&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void modifyValues(int *a, short *b) {
  *b = 3;
  *a = 47;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In this case, the final value of n would be 47.&lt;/p&gt;&lt;p data-block-key=&quot;ddqj3&quot;&gt;Though, is that program right in this case? Obviously, it is not. There is undefined behavior, which is visible through how different optimization levels have different results.&lt;/p&gt;&lt;p data-block-key=&quot;3a1a7&quot;&gt;Why is that?&lt;/p&gt;&lt;p data-block-key=&quot;98o38&quot;&gt;In accordance with the C and C++ standards, when you try to access an object of one type (e.g., int) using an lvalue expression of a different type (e.g., short in a function argument), and these types are not considered compatible (except for specific exceptions outlined in the standards), it leads to undefined behavior. This means that the program&apos;s behavior cannot be predicted or relied upon, and it may produce unexpected results.&lt;/p&gt;&lt;p data-block-key=&quot;3lt8j&quot;&gt;Personally speaking, I really like when undefined behavior teaches much more about programming than the defined behavior. :)&lt;/p&gt;&lt;h2 id=&quot;tbaa-in-action:&quot; data-block-key=&quot;keqy1&quot;&gt;TBAA in Action:&lt;/h2&gt;&lt;p data-block-key=&quot;5s3mo&quot;&gt;Consider the following example:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void Foo(float *v, int *n) {
  for (int i = 0; i &amp;lt; *n; i++)
    v[i] += 1.0f;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In this case, the compiler and TBAA ensure that the types are not compatible and memory lookup for *n can be optimized by performing it just once. The resulting value can be stored in a register, which is then accessed in each iteration of the loop. This optimization helps reduce memory access overhead and can lead to improved performance.&lt;/p&gt;&lt;p data-block-key=&quot;450c&quot;&gt;Now, consider this example:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void Foo(float v[], float *c, int n) {
  for (int i = 0; i &amp;lt; n; i++)
    v[i] = *c + 1.0f;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In the provided example, the types of &lt;b&gt;v&lt;/b&gt; and &lt;b&gt;c&lt;/b&gt; are compatible, which leads the compiler to assume they may alias, meaning they could refer to the same memory location. Consequently, the compiler takes measures to ensure that fetching the value of &lt;b&gt;*c&lt;/b&gt; within the loop will indeed be performed in each iteration. This behavior is implemented to guarantee that the value pointed to by &lt;b&gt;c&lt;/b&gt; is fetched afresh in every iteration of the loop. However, it&apos;s important to note that this meticulous handling, while beneficial for correctness, can potentially impact performance.&lt;/p&gt;&lt;h2 id=&quot;for-more-details-let&amp;#x27;s-look-at-their-assembly&quot; data-block-key=&quot;zqb1d&quot;&gt;For More Details Let&apos;s Look at their Assembly&lt;/h2&gt;&lt;p data-block-key=&quot;qg92&quot;&gt;&lt;b&gt;First Version (Non-compatible types):&lt;/b&gt;&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;Foo(float*, int*):
    movsx rax, DWORD PTR [rsi]
    test eax, eax
    jle .L1
    movss xmm1, DWORD PTR .LC0[rip]
    lea rax, [rdi+rax*4]
.L3:
    movss xmm0, DWORD PTR [rdi]
    add rdi, 4
    addss xmm0, xmm1
    movss DWORD PTR [rdi-4], xmm0
    cmp rdi, rax
    jne .L3
.L1:
    ret&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;&lt;b&gt;Second Version (Compatible types):&lt;/b&gt;&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;Foo(float*, float*, int):
    test edx, edx
    jle .L1
    movsx rdx, edx
    movss xmm1, DWORD PTR .LC0[rip]
    lea rax, [rdi+rdx*4]
.L3:
    movss xmm0, DWORD PTR [rsi]
    add rdi, 4
    addss xmm0, xmm1
    movss DWORD PTR [rdi-4], xmm0
    cmp rdi, rax
    jne .L3&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In the first version &lt;b&gt;(Foo(float*, int*))&lt;/b&gt;, the loop counter n is passed as a pointer to an integer &lt;b&gt;(int*)&lt;/b&gt;. The code loads this integer value &lt;b&gt;(*n)&lt;/b&gt; into a register &lt;b&gt;(rax)&lt;/b&gt; before entering the loop, and then uses this register for loop control.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;movsx rax, DWORD PTR [rsi]&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;This means that the loop counter is loaded from memory once at the beginning of the loop, and the register value is used throughout the loop iterations.&lt;/p&gt;&lt;p data-block-key=&quot;ftm48&quot;&gt;In the second version in each iteration of the loop, &lt;b&gt;*c&lt;/b&gt; is loaded into xmm0.&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;movss xmm0, DWORD PTR [rsi]&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;This behavior ensures that the value pointed to by &lt;b&gt;*c&lt;/b&gt; is consistent throughout the loop iterations.&lt;/p&gt;&lt;p data-block-key=&quot;bravk&quot;&gt;Have you noticed how type-based alias analysis benefits compilers to take optimizations action?&lt;/p&gt;&lt;p data-block-key=&quot;7fuso&quot;&gt;But the question remains:&lt;br/&gt;What is an explicit fix for this, or hint to the compiler that there is no chance of aliasing even in the case of compatible types?&lt;/p&gt;&lt;p data-block-key=&quot;7045t&quot;&gt;In C, the restrict keyword comes to the rescue when you want to explicitly inform the compiler that there is no chance of aliasing between pointers.&lt;/p&gt;&lt;p data-block-key=&quot;e5qpv&quot;&gt;Consider this example:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-cpp  line-numbers &quot;&gt;void Foo(float* restrict v, float* c, int n) {
  for (int i = 0; i &amp;lt; n; i++)
    v[i] = *c + 1.0f;
}&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;In practice, you may need to declare both pointers as restrict if you can guarantee that they don&apos;t alias each other.&lt;/p&gt;&lt;h3 id=&quot;let&amp;#x27;s-look-at-the-assembly-for-the-above-code:&quot; data-block-key=&quot;qc8uy&quot;&gt;Let&apos;s Look at the Assembly for the Above Code:&lt;/h3&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;Foo:
test edx, edx
jle .L1
movsx rdx, edx
movss xmm0, DWORD PTR .LC0[rip]
lea rax, [rdi+rdx*4]
and edx, 1
je .L3
movss DWORD PTR [rdi], xmm0
add rdi, 4
and edx, 1
je .L11
.L3:
movss DWORD PTR [rdi], xmm0
add rdi, 8
movss DWORD PTR [rdi-4], xmm0
cmp rdi, rax
je .L11&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;See how it impacted the performance:&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;formatted-code&quot;&gt;
    &lt;pre&gt;&lt;code class=&quot;language-nasm  line-numbers &quot;&gt;movss xmm0, DWORD PTR .LC0[rip]  ; Load 1.0f into xmm0
addss xmm0, DWORD PTR [rsi]      ; Add *c to xmm0&lt;/code&gt;&lt;/pre&gt;
 &lt;/div&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;ovtrz&quot;&gt;The &lt;b&gt;movss&lt;/b&gt; instruction loads the constant 1.0f into &lt;b&gt;xmm0&lt;/b&gt;, and then &lt;b&gt;addss&lt;/b&gt; adds the value pointed to by &lt;b&gt;&lt;i&gt;c&lt;/i&gt;&lt;/b&gt;&lt;i&gt; to&lt;/i&gt; &lt;b&gt;&lt;i&gt;xmm0&lt;/i&gt;&lt;/b&gt;&lt;i&gt;.&lt;/i&gt; Importantly&lt;i&gt;,&lt;/i&gt; &lt;b&gt;c&lt;/b&gt; is loaded into &lt;b&gt;xmm0&lt;/b&gt; only once outside the loop and re-used in the loop. Using the &lt;b&gt;restrict&lt;/b&gt; keyword, you provide the compiler with the assurance that the memory regions accessed through the pointers &lt;b&gt;v&lt;/b&gt; and &lt;b&gt;c&lt;/b&gt; do not overlap. The compiler can then optimize the code more aggressively for performance.&lt;/p&gt;&lt;p data-block-key=&quot;4ljbk&quot;&gt;However, a word of caution: you must be very careful when using restrict, as the compiler won&apos;t warn you about its incorrect use.&lt;/p&gt;&lt;p data-block-key=&quot;10qv5&quot;&gt;Interestingly, the restrict keyword is not a part of C++. Why is that?&lt;/p&gt;&lt;p data-block-key=&quot;9sgmd&quot;&gt;The history behind this decision is quite intriguing. When reviewing C99 features for inclusion in C++, there was consideration of adding &lt;a href=&quot;https://www.geeksforgeeks.org/restrict-keyword-c/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;restrict&lt;/b&gt;&lt;/a&gt;. However, no paper proposal was made at the time. Hence, it didn&apos;t make its way into C++.&lt;/p&gt;&lt;p data-block-key=&quot;ckhli&quot;&gt;&lt;b&gt;restrict&lt;/b&gt; was originally designed for fine-grain aliasing in C but may not be well-suited for the type-based aliasing that is more common in C++. In C++, pointers are less prevalent in class abstractions and restrict may not align well with the C++ language design.&lt;/p&gt;&lt;p data-block-key=&quot;ci7p3&quot;&gt;In summary, the restrict keyword in C and type-based alias analysis are tools that help compilers generate efficient and optimized code while maintaining program correctness and adherence to language standards.&lt;/p&gt;&lt;p data-block-key=&quot;1i6ok&quot;&gt;Thank you for reading!&lt;/p&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/understanding-type-based-alias-analysis-in-c-and-cpp/&quot;&gt;Understanding Type-Based Alias Analysis in C and C++&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><category>c++</category><category>performance</category><category>tools</category></item><item><title>KDAB at Embedded World NA 2025</title><link>https://www.kdab.com/kdab-at-embedded-world-na-2025/</link><guid isPermaLink="true">https://www.kdab.com/kdab-at-embedded-world-na-2025/</guid><description>&lt;p data-block-key=&quot;pvuv9&quot;&gt;KDAB will be exhibiting at &lt;b&gt;Embedded World North America&lt;/b&gt; from &lt;b&gt;November 4th through 6th, 2025&lt;/b&gt;, in Anaheim, California.&lt;/p&gt;</description><pubDate>Tue, 21 Oct 2025 06:51:00 GMT</pubDate><content:encoded>&lt;h1&gt;KDAB at Embedded World NA 2025&lt;/h1&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;0n636&quot;&gt;KDAB will be exhibiting at &lt;a href=&quot;https://embedded-world-na.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;Embedded World North America&lt;/b&gt;&lt;/a&gt; from &lt;b&gt;November 4th through 6th, 2025&lt;/b&gt;, in Anaheim, California.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;Event Details:&lt;/h2&gt;
&lt;p&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;rwxf7&quot;&gt;📍 Anaheim, California&lt;br/&gt;📅 November 4–6, 2025&lt;br/&gt;📍 KDAB Booth: 5039&lt;/p&gt;&lt;p data-block-key=&quot;bj43n&quot;&gt;Get your tickets &lt;a href=&quot;https://www.prereg.net/2025/ewna/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/p&gt;


&lt;div class=&quot;rich-text&quot;&gt;&lt;h2 id=&quot;explore-kdab-demos&quot; data-block-key=&quot;pbqxu&quot;&gt;&lt;b&gt;Explore KDAB Demos&lt;/b&gt;&lt;/h2&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;live-3d-ui-for-autonomous-public-transport&quot; data-block-key=&quot;32a80&quot;&gt;Live 3D UI for Autonomous Public Transport&lt;/h3&gt;&lt;p data-block-key=&quot;124qn&quot;&gt;&lt;i&gt;The UI displays the autonomous driver&apos;s real-time awareness and planned actions to the vehicle users.&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;ed3pm&quot;&gt;Autonomous bus driven by &lt;a href=&quot;https://www.motor-ai.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Motor AI&lt;/a&gt; infrastructure&lt;/li&gt;&lt;li data-block-key=&quot;9cl3j&quot;&gt;Interactive 3D dashboard powered by Serenity&lt;/li&gt;&lt;li data-block-key=&quot;343s4&quot;&gt;Real-time data streamed via MQTT&lt;/li&gt;&lt;li data-block-key=&quot;dsb87&quot;&gt;Touch interface built with &lt;a href=&quot;https://slint.dev/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Slint&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;qt-gstreamer-multi-display&quot; data-block-key=&quot;eah4p&quot;&gt;Qt GStreamer Multi-Display&lt;/h3&gt;&lt;p data-block-key=&quot;khdb&quot;&gt;&lt;i&gt;Stream Qt applications to Multiple Browser Instances&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;6d3fj&quot;&gt;Standard Qt/QML Application on an Intel Atom-based CPU&lt;/li&gt;&lt;li data-block-key=&quot;9gofm&quot;&gt;Complex GStreamer pipeline to transform into a WebRTC stream&lt;/li&gt;&lt;li data-block-key=&quot;cfjfb&quot;&gt;Results viewable in any WebRTC-capable browser&lt;/li&gt;&lt;li data-block-key=&quot;kn8n&quot;&gt;Full touch input and interactivity across multiple screens&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;medical-tool-for-interventional-cardiac-imaging&quot; data-block-key=&quot;piitf&quot;&gt;Medical tool for interventional cardiac imaging&lt;/h3&gt;&lt;p data-block-key=&quot;6tjf0&quot;&gt;&lt;a href=&quot;https://www.kdab.com/why-kdab/proven-excellence/luma-vision/&quot;&gt;&lt;i&gt;LUMA Vision and KDAB&lt;/i&gt;&lt;/a&gt;&lt;i&gt; developed a fully software-defined, end-to-end imaging system that could adapt to market and clinical needs.&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;52lk&quot;&gt;Uses Qt3D/Vulkan for visualisation of ultrasound data&lt;/li&gt;&lt;li data-block-key=&quot;a5a29&quot;&gt;Uses QML for 2D user interface&lt;/li&gt;&lt;li data-block-key=&quot;22mt&quot;&gt;CUDA-based 3D data processing&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;
&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;performance-optimization-tools&quot; data-block-key=&quot;sg5y1&quot;&gt;Performance optimization tools&lt;/h3&gt;&lt;p data-block-key=&quot;6nnab&quot;&gt;&lt;i&gt;For developers using Qt, C++, and Linux&lt;/i&gt;&lt;/p&gt;&lt;ul&gt;&lt;li data-block-key=&quot;bf31v&quot;&gt;&lt;a href=&quot;https://www.kdab.com/gammaray-3-3-released/&quot;&gt;GammaRay&lt;/a&gt;: High-level introspection tool for Qt applications&lt;/li&gt;&lt;li data-block-key=&quot;3l1u4&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/hotspot/&quot;&gt;Hotspot&lt;/a&gt;: The Linux perf GUI for performance analysis&lt;/li&gt;&lt;li data-block-key=&quot;13bot&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/kddockwidgets/&quot;&gt;KDDockWidgets&lt;/a&gt;: KDAB&apos;s Dock Widget Framework for Qt&lt;/li&gt;&lt;li data-block-key=&quot;brjin&quot;&gt;&lt;a href=&quot;https://www.kdab.com/clazy-results-visualizer-qt/&quot;&gt;Clazy&lt;/a&gt; Static Code Analyzer: LLVM/Clang-based static analyzer for Qt&lt;/li&gt;&lt;li data-block-key=&quot;cjqhm&quot;&gt;&lt;a href=&quot;https://www.kdab.com/heaptrack-demo-video/&quot;&gt;Heaptrack&lt;/a&gt;: Heap memory profiler and analysis GUI for Linux&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;

&lt;div class=&quot;rich-text&quot;&gt;&lt;h3 id=&quot;meet-kdab-engineers&quot; data-block-key=&quot;1t3na&quot;&gt;&lt;b&gt;Meet KDAB Engineers&lt;/b&gt;&lt;/h3&gt;&lt;p data-block-key=&quot;a2tcv&quot;&gt;Let&apos;s discuss your specific &lt;b&gt;C++, Qt, Rust, and 3D development challenges.&lt;/b&gt; Visit KDAB in &lt;b&gt;booth 5039.&lt;/b&gt;&lt;/p&gt;&lt;p data-block-key=&quot;a31sr&quot;&gt;We look forward to connecting with you in Anaheim!&lt;/p&gt;&lt;/div&gt;


&lt;div class=&quot;image-variable-size-block&quot;&gt;
    &lt;div class=&quot;image-variable-positioning-block right-margin-auto left-margin-auto width-100 &quot; &gt;
            &lt;div class=&quot;image-variable-size-image&quot;&gt;
                
                
                    &lt;a href=&quot;https://embedded-world-na.com/&quot; title=&quot;Embedded World NA&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot; &gt;
                
                
                &lt;img id=&quot;Embedded World NA&quot; src=&quot;https://eu-central-1.linodeobjects.com/wagtail-production/images/embedded-world-north-america-logo.original.png&quot; class=&quot;Embedded World NA&quot; alt=&quot;Embedded World NA&quot;&gt;
                
                
                    &lt;/a&gt;
                
        &lt;/div&gt;
        &lt;div class=&quot;image-variable-size-caption text-end&quot;&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/kdab-at-embedded-world-na-2025/&quot;&gt;KDAB at Embedded World NA 2025&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator></item><item><title>GammaRay 3.3 Released</title><link>https://www.kdab.com/gammaray-3-3-released/</link><guid isPermaLink="true">https://www.kdab.com/gammaray-3-3-released/</guid><description>&lt;p data-block-key=&quot;8qq42&quot;&gt;GammaRay 3.3 introduces several updates aimed at maintaining compatibility with current Qt versions and improving stability across platforms.&lt;/p&gt;</description><pubDate>Mon, 20 Oct 2025 13:19:00 GMT</pubDate><content:encoded>&lt;h1&gt;GammaRay 3.3 Released&lt;/h1&gt;&lt;div class=&quot;rich-text&quot;&gt;&lt;p data-block-key=&quot;9o0v3&quot;&gt;&lt;a href=&quot;https://github.com/KDAB/GammaRay/releases/tag/v3.3.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;GammaRay 3.3&lt;/a&gt; is now available.&lt;/p&gt;&lt;p data-block-key=&quot;f07t3&quot;&gt;&lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/gammaray/&quot;&gt;GammaRay&lt;/a&gt; is a tool for developers working with the Qt framework, offering deep inspection capabilities that help you analyze, debug, and understand your applications at runtime. It provides insight into the behavior and state of Qt objects while the application is running, allowing for efficient troubleshooting, performance tuning, and exploration of complex UI or logic issues.&lt;/p&gt;&lt;h2 id=&quot;what&amp;#x27;s-new-in-gammaray-3.3&quot; data-block-key=&quot;wuko4&quot;&gt;What’s new in GammaRay 3.3&lt;/h2&gt;&lt;p data-block-key=&quot;e6097&quot;&gt;&lt;a href=&quot;https://github.com/KDAB/GammaRay/releases/tag/v3.3.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Version 3.3&lt;/a&gt; introduces several updates aimed at maintaining compatibility with current Qt versions and improving stability across platforms.&lt;/p&gt;&lt;p data-block-key=&quot;bsbur&quot;&gt;GammaRay has &lt;b&gt;dropped support for Qt 5&lt;/b&gt;, with the &lt;b&gt;minimum supported version now set to Qt 6.5&lt;/b&gt;. For developers who still rely on Qt 5, the 3.2 branch will continue to receive maintenance releases where necessary, including critical bug fixes and backports. This transition allows GammaRay to focus on modern Qt capabilities and simplifies ongoing development.&lt;/p&gt;&lt;p data-block-key=&quot;38ipk&quot;&gt;On Windows, &lt;b&gt;support for LLVM MinGW&lt;/b&gt; has been added, expanding the range of supported toolchains. A long-standing issue where the &lt;b&gt;GammaRay user interface&lt;/b&gt; would occasionally fail to appear on Windows has also been resolved.&lt;/p&gt;&lt;p data-block-key=&quot;e1gtn&quot;&gt;Additional improvements include updating the &lt;b&gt;LZ4 compression library to version 1.10.0&lt;/b&gt; and fixing build compatibility with &lt;b&gt;Qt 6.10&lt;/b&gt;, ensuring GammaRay continues to integrate smoothly with the latest Qt releases.&lt;/p&gt;&lt;p data-block-key=&quot;b025b&quot;&gt;You can find the full list of changes and downloads for this release on &lt;a href=&quot;https://github.com/KDAB/GammaRay/releases/tag/v3.3.0&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;p data-block-key=&quot;6omod&quot;&gt;We look forward to feedback from users as they integrate GammaRay 3.3 into their workflows and encourage those still on older Qt versions to follow the 3.2 branch for continued support.&lt;/p&gt;&lt;h3 id=&quot;videos&quot; anchor=&quot;videos&quot; data-block-key=&quot;hqe6m&quot;&gt;Videos about GammaRay&lt;/h3&gt;&lt;ul&gt;&lt;li data-block-key=&quot;8boj3&quot;&gt;GammaRay Tutorials: &lt;a href=&quot;https://www.youtube.com/playlist?list=PL6CJYn40gN6itybeSJb5FvRWOxVW5PCUX&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/playlist?list=PL6CJYn40gN6itybeSJb5FvRWOxVW5PCUX&lt;/a&gt;&lt;/li&gt;&lt;li data-block-key=&quot;dfeau&quot;&gt;GammaRay Tutorials for Qt Widgets Applications: &lt;a href=&quot;https://www.youtube.com/playlist?list=PL6CJYn40gN6izGNDIH06YXf0UzR_1BVhn&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;https://www.youtube.com/playlist?list=PL6CJYn40gN6izGNDIH06YXf0UzR_1BVhn&lt;/a&gt;&lt;/li&gt;&lt;li data-block-key=&quot;2pjq7&quot;&gt;More info on GammaRay: &lt;a href=&quot;https://www.kdab.com/software-technologies/developer-tools/gammaray/&quot;&gt;https://www.kdab.com/software-technologies/developer-tools/gammaray/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;The post &lt;a href=&quot;https://www.kdab.com/gammaray-3-3-released/&quot;&gt;GammaRay 3.3 Released&lt;/a&gt; appeared first on &lt;a href=&quot;https://www.kdab.com&quot;&gt;KDAB&lt;/a&gt;.&lt;/p&gt;</content:encoded><dc:creator>Editor Team</dc:creator><category>tools</category></item></channel></rss>