DIY embedded development and C++
This is my first post on this platform and I want to share my recent experience in DIY embedded world and the software development for it.
During my quite long career I mostly used C++ as a main programming language. As every tool this language have its own area of the best applicability and this area is wide. Combining support of multiple paradigms with zero cost abstractions and precise control of program's execution it allows to write efficient and maintainable code for almost any task. But there is one area where C++ is not so popular as it could be. This area is embedded development.
When some time ago I decided to build my own air quality sensor I (surprisingly) found the majority of embedded projects are still written on C or use C++ as ugly "C with classes" leaving most of its benefits untouched.
So why C++ still is not popular in embedded development? There are for sure some historical reasons. Decades ago the support for C++ was not so good as for C on the embedded platforms, the hardware was not so powerful and the compilers were not so smart. Many embedded devices were programmed in assembler and C was treated as a high level language. At the time of 90th C++ was not a good choice for them. And still many embedded developers think that it's true even nowadays.
Recommended by LinkedIn
But there is year 2023. What was changed within 30 years? Lot of things, and C++ is one of them. It became a very different language when C++11 brought move semantics, lambdas, constexpr, variadic templates and many other features. C++14 was mostly a refinement, but C++17 brought a lot of new features like constexpr if, std::optional, structured bindings, parallel algorithms, improved string handling and many others.
Constexpr if allows to write more expressive and efficient code by eliminating unnecessary branches at compile time. It's clear and safe alternative to macros and preprocessor conditional directives. The std::optional class implement an idiom of 'value or nothing' instead of using pointers or special values. It's safe and expressive alternative to pointers and special values. Moreover, it allows to construct and destroy object it handle at runtime without usage of the heap. You can use nontrivial constructors and destructors even if you don't have a heap at all. Structured bindings allow multiple variables to be declared and initialized from a single expression. This feature can simplify code and make it more concise, improving readability and maintainability. Mandatory copy elision allows to write more efficient code by eliminating unnecessary copies, especially in the case of returning objects from functions.
For a long time in C world the word "string" means "zero-terminated string" or a sequence of chars terminated by trailing zero and designated by pointer to first character. Lot of code depends on this assumption, lot of buffers were overloaded since then. Finally C++17 introduced std::string_view which is a non-owning reference to a string contain a pointer to the beginning and length. It's hard to overestimate the importance of this feature for both performance and safety.
There are many other new or improved features in C++17. Combined they allow to write more efficient, more expressive and more safe code. It's shown many times that the same algorithm written in C++17 is at least not less efficient than in C besides the C++ code is more simple, expressive and more safe. The problem is, there are lack of libraries for embedded development written in modern C++. And while I'm not an embedded developer on my main job, I decided to write a simple embedded framework using C++17 (a version available now for all popular platforms) which I can use in my own projects and open it to public. The framework and two projects use it are available on my GitHub page.