Trusted Software Excellence across Desktop and Embedded
Take a glance at the areas of expertise where KDAB excels ranging from swift troubleshooting, ongoing consulting and training to multi-year, large-scale software development projects.
Find out why customers from innovative industries rely on our extensive expertise, including Medical, Biotech, Science, Renewable Energy, Transportation, Mobility, Aviation, Automation, Electronics, Agriculture and Defense.
High-quality Embedded Engineering across the Stack
To successfully develop an embedded device that meets your expectations regarding quality, budget and time to market, all parts of the project need to fit perfectly together.
Learn more about KDAB's expertise in embedded software development.
Where the capabilities of modern mobile devices or web browsers fall short, KDAB engineers help you expertly architect and build high-functioning desktop and workstation applications.
Extensible, Safety-compliant Software for the Medical Sector
Create intelligent, patient-focused medical software and devices and stay ahead with technology that adapts to your needs.
KDAB offers you expertise in developing a broad spectrum of clinical and home-healthcare devices, including but not limited to, internal imaging systems, robotic surgery devices, ventilators and non-invasive monitoring systems.
Building digital dashboards and cockpits with fluid animations and gesture-controlled touchscreens is a big challenge.
In over two decades of developing intricate UI solutions for cars, trucks, tractors, scooters, ships, airplanes and more, the KDAB team has gained market leading expertise in this realm.
Build on Advanced Expertise when creating Modern UIs
KDAB assists you in the creation of user-friendly interfaces designed specifically for industrial process control, manufacturing, and fabrication.
Our specialties encompass the custom design and development of HMIs, enabling product accessibility from embedded systems, remote desktops, and mobile devices on the move.
Legacy software is a growing but often ignored problem across all industries. KDAB helps you elevate your aging code base to meet the dynamic needs of the future.
Whether you want to migrate from an old to a modern GUI toolkit, update to a more recent version, or modernize your code base, you can rely on over 25 years of modernization experience.
KDAB offers a wide range of services to address your software needs including consulting, development, workshops and training tailored to your requirements.
Our expertise spans cross-platform desktop, embedded and 3D application development, using the proven technologies for the job.
When working with KDAB, the first-ever Qt consultancy, you benefit from a deep understanding of Qt internals, that allows us to provide effective solutions, irrespective of the depth or scale of your Qt project.
Qt Services include developing applications, building runtimes, mixing native and web technologies, solving performance issues, and porting problems.
KDAB helps create commercial, scientific or industrial desktop applications from scratch, or update its code or framework to benefit from modern features.
Discover clean, efficient solutions that precisely meet your requirements.
Boost your team's programming skills with in-depth, constantly updated, hands-on training courses delivered by active software engineers who love to teach and share their knowledge.
Our courses cover Modern C++, Qt/QML, Rust, 3D programming, Debugging, Profiling and more.
The collective expertise of KDAB's engineering team is at your disposal to help you choose the software stack for your project or master domain-specific challenges.
Our particular focus is on software technologies you use for cross-platform applications or for embedded devices.
Since 1999, KDAB has been the largest independent Qt consultancy worldwide and today is a Qt Platinum partner. Our experts can help you with any aspect of software development with Qt and QML.
KDAB specializes in Modern C++ development, with a focus on desktop applications, GUI, embedded software, and operating systems.
Our experts are industry-recognized contributors and trainers, leveraging C++'s power and relevance across these domains to deliver high-quality software solutions.
KDAB can guide you incorporating Rust into your project, from as overlapping element to your existing C++ codebase to a complete replacement of your legacy code.
Unique Expertise for Desktop and Embedded Platforms
Whether you are using Linux, Windows, MacOS, Android, iOS or real-time OS, KDAB helps you create performance optimized applications on your preferred platform.
If you are planning to create projects with Slint, a lightweight alternative to standard GUI frameworks especially on low-end hardware, you can rely on the expertise of KDAB being one of the earliest adopters and official service partner of Slint.
KDAB has deep expertise in embedded systems, which coupled with Flutter proficiency, allows us to provide comprehensive support throughout the software development lifecycle.
Our engineers are constantly contributing to the Flutter ecosystem, for example by developing flutter-pi, one of the most used embedders.
KDAB invests significant time in exploring new software technologies to maintain its position as software authority. Benefit from this research and incorporate it eventually into your own project.
Start here to browse infos on the KDAB website(s) and take advantage of useful developer resources like blogs, publications and videos about Qt, C++, Rust, 3D technologies like OpenGL and Vulkan, the KDAB developer tools and more.
The KDAB Youtube channel has become a go-to source for developers looking for high-quality tutorial and information material around software development with Qt/QML, C++, Rust and other technologies.
Click to navigate the all KDAB videos directly on this website.
In over 25 years KDAB has served hundreds of customers from various industries, many of them having become long-term customers who value our unique expertise and dedication.
Learn more about KDAB as a company, understand why we are considered a trusted partner by many and explore project examples in which we have proven to be the right supplier.
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications.
Read more about the history, the values, the team and the founder of the company.
When working with KDAB you can expect quality software and the desired business outcomes thanks to decades of experience gathered in hundreds of projects of different sizes in various industries.
Have a look at selected examples where KDAB has helped customers to succeed with their projects.
KDAB is committed to developing high-quality and high-performance software, and helping other developers deliver to the same high standards.
We create software with pride to improve your engineering and your business, making your products more resilient and maintainable with better performance.
KDAB has been the first certified Qt consulting and software development company in the world, and continues to deliver quality processes that meet or exceed the highest expectations.
In KDAB we value practical software development experience and skills higher than academic degrees. We strive to ensure equal treatment of all our employees regardless of age, ethnicity, gender, sexual orientation, nationality.
Interested? Read more about working at KDAB and how to apply for a job in software engineering or business administration.
erasing elements from the middle of a vector can be implemented, in general, via a series of move assignments, move constructions, swaps, destructions
for types with value semantics, the exact strategy does not really matter
for types with write-through reference semantics, the strategy matters, because the outcome is different
for this reason, the Standard Library specifies exactly which strategy is employed: move assignments and destructions
Qt optimizes erasure of trivially relocatable types by using memmove to compact the tail.
We ended up realizing that this creates a contradiction: a type with write-through reference semantics like std::tuple<int &> is trivially relocatable (move construction and destruction of the source can be replaced by moving bytes), but it cannot be erased via byte manipulations. However, if we were to mark that type as trivial relocatable (via Q_DECLARE_TYPEINFO) then Qt would use byte manipulations, breaking our programs!
The conclusion of the last post was that we need to change something in our models:
maybe std::vector should use a different strategy when erasing elements
maybe types like std::tuple<int &> should not be allowed to be stored in a vector
maybe Qt should not be using memmove when erasing objects of trivially relocatable type (but it can still optimize the reallocation of a vector)
maybe Qt's definition of trivial relocability does not match ours, and we need to fix our definitions.
In this post we will explore these possibilities and reach some conclusions.
Changing the behavior of vector erasure
As we have already discussed in the previous blog posts, it is possible to implement erasure in a number of ways, which are not equivalent. The Standard Library chose a specific implementation strategy (move-assign the elements after the ones to be destroyed to the left; destroy the moved-from last elements). Changing it now, over 26 years after the fact, sounds extremely scary; std::vector is such a central class that surely such a change would break somebody's code.
That doesn't mean that we can't at least reason about a possible change there!
Also, there is another library that we keep talking about in these blog posts. This other library has a much smaller userbase than the Standard Library, and that has fewer regards with breaking backwards compatibility. We should certainly reason about that library as well. I'm talking about Qt, of course :)
Change the behavior of vector erasure what, exactly?
In order to reconcile our definition of (trivial) relocatability with the behavior of erase, we would need to implement erase in terms of move constructions and destructions.
Thankfully, this can be done. Suppose again we want to erase the second element from a vector:
Same problem: how to erase B from the vector?
We can implement this by destroying the second element, and move-constructing the third element over it:
First steps: B gets destroyed; C is move-constructed over it.
Then we destroy the moved-from third element, and move-construct the fourth element over it.
Destroy the moved-from C object, move-construct D over it
We keep going until the end, where we have just a moved-from element to destroy:
Destroy moved-from D. It's the last element, nothing else to move around. Update bookkeeping and we're done.
Erasure can use relocation
The fact that this particular implementation strategy is viable gives us some very interesting insights.
Let's look at the sequence of operations once again:
Destroy the element at position 1 (B)
Move construct the element at position 2 into position 1 (C)
Destroy the element at position 2 (moved-from C)
Move construct the element at position 3 into position 2 (D)
Destroy the element at position 3 (moved-from D)
We can look at this sequence in two different ways:
firstly, as pairs of "destroy + move construct" operations, leaving a last element to destroy (1+2, 3+4, 5)
or, more interestingly, as an initial destruction, followed by a series of relocations. (1, 2+3, 4+5).
Move assignments for value types
Let's analyze the first way: pairs of "destruction + move construction" operations. This analysis will allow us to grasp the fundamental difference between value types (like QString, or std::unique_ptr<T>) from reference types (like std::tuple<int &>).
We have already established that for a value type it does not matter what the erasure strategy is; the outcome is the same. For a write-through reference type, the strategy matters; using move assignments instead of destructions/move constructions pairs will yield a different result.
We can now appreciate the difference: for a value type, a move assignment is equivalent to destruction of the target, followed by move construction. This is why, when dealing with value types, using the above strategy for erasure gives us the same results as a strategy based on move assignments (like the one that std::vector uses).
For a write-through reference type, this is not true: a move assignment is not equivalent to destroying the target and move-constructing the source in its place. Again, consider std::tuple<int &>:
int a =1;int b =2;using T = std::tuple<int&>;T ta(a);T tb(b);#ifUSE_MOVE_ASSIGN// move-assignment from tbta = std::move(tb);// a = 2, b = 2#else// destroy ta + move-construct from tbta.~T();new(&ta)T(std::move(tb));// a = 1, b = 2#endif
It is worth noticing the behavior of move assigments is completely orthogonal to whether a type is trivially relocatable or not. Both QString and std::tuple<int &>: are trivially relocatable (according to our prior definition), but QString has value semantics, std::tuple<int &>: has not. In other words, this is another property of a type which cannot be "detected" from the outside the type itself (just like trivial relocation cannot be detected).
Trivial relocation and erasure
Let's now tackle the second way of looking at erasure: destruction of an element, followed by a series of relocations.
This means that if a type is trivially relocatable, then the erasure strategy shown above can be implemented by an initial destruction followed by a memory copy for each subsequent element. Of course, these byte copies can be coalesced in a single memmove of the tail:
This is precisely what Qt does when erasing elements of a trivially relocatable type! At least now we have a justification for it.
So which erasure strategy does QVector use exactly?
If Qt uses trivial relocation to erase elements from a QVector of trivially relocatable types, does this mean that QVector also uses (non-trivial) relocation when erasing objects of other types?
Well... no, not really. Qt is way, way, way less strict than the C++ Standard Library: the exact strategies for erasure, insertion etc. are simply undocumented and can and will change at any time. (In fact, as I'm writing this blog post, I can see commits that change these algorithms...) The strategies are also inconsistent between different containers.
For instance, consider a non-empty QVector of size S. If I erase the first element, exactly how many operations are going to happen? 𝒪(S), right?
That would be true in Qt 5, but it's not true any more in Qt 6! In Qt 6 the operation is 𝒪(1): QVector in Qt 6 has a "prepend optimization": there may be empty capacity at both ends of the storage. So, in order to erase the first element, it's sufficient to destroy it and update bookkeeping (move the "begin" pointer forward). This is just one amongst many other similar examples where Qt containers have changed behavior between Qt releases; other changes do happen even between minor releases.
The corollary is of this lack of guarantees is quite strong: do not ever store types that don't have value semantics in Qt containers! Qt will break your programs when its containers change behavior. It's a when, not an if.
Thankfully, the majority of types we deal with in Qt applications have value semantics, so they are not affected.
Could we just ban non-value types from containers?
There is one last question left. Who in the world uses std::tuple<int &> as a vector's value type?
While that may sound very unlikely, in reality there are many other types for which assignment is different than destruction+move construction.
For instance: allocator-aware types (std::string, std::vector, etc.) may exhibit non-value behavior with certain allocators. An example of such an allocator is std::pmr::polymorphic_allocator, which does not propagate on move assignment. Erasing a std::pmr::string from a vector must have a very specific outcome, dictated by its reference semantics; but surely we can't outlaw vector of strings!
Even if we could decide to ban "some" types, how do we figure out their assignment semantics?. A Rule Of Five type may or may not have value semantics, and there is no way to know about that "from the outside".
So, this line of reasoning leads to nowhere.
Conclusions
In this post we started with a list of questions. In search for answers, we have have seen that:
for some types ("value" types), move assignment is equivalent to destruction of the target followed by move construction from the source, while for other types this is not true
we can't just ban the latter types from being stored in containers. They're useful, and in general we have no means to detect them!
vector erasure can be implemented in terms of relocations: this fact potentially allows a vector implementation (like QVector) to use trivial relocation when erasing elements
Qt containers assume value semantics from the objects they hold, and do not document the exact strategies used by their algorithms
we can't change std::vector erasure behavior, because it would break existing code.
In the next post we will finish our exploration of trivial relocability, and we'll look at C++ standardization. Thank you for reading!
Trusted software excellence across embedded and desktop platforms
The KDAB Group is a globally recognized provider for software consulting, development and training, specializing in embedded devices and complex cross-platform desktop applications. In addition to being leading experts in Qt, C++ and 3D technologies for over two decades, KDAB provides deep expertise across the stack, including Linux, Rust and modern UI frameworks. With 100+ employees from 20 countries and offices in Sweden, Germany, USA, France and UK, we serve clients around the world.
Senior Software Engineer at KDAB. Giuseppe is a long-time contributor to Qt, having used Qt and C++ since 2000, and is an Approver in the Qt Project. His contributions in Qt range from containers and regular expressions to GUI, Widgets, and OpenGL. A free software passionate and UNIX specialist, before joining KDAB, he organized conferences on opensource around Italy. He holds a BSc in Computer Science.
Our hands-on Modern C++ training courses are designed to quickly familiarize newcomers with the language. They also update professional C++ developers on the latest changes in the language and standard library introduced in recent C++ editions.