Most big C++ projects lack a clear structure: They consist of multiple modules, but it is not as easy to create individually buildable, portable, testable, and reusable libraries from them, as it is with projects written in Rust, Go, Haskell, etc. In this article, I propose a C++ project structure using CMake that makes it easy to have incremental monorepo builds and a nice modular structure at the same time.
I never install toolchains globally on my systems. Instead, every project comes with its own nix file that describes the complete development toolchain versions and dependencies. This way, fresh checkouts always build the same way on every machine. This week I would like to show you how I set up a C++ project with the Qt Quick framework, and how to package the app and make it runnable for other nix users.
This article explains how to quickly set up a C++ project environment with
complete toolchain- and dependency management with
nix is a powerful package manager for Linux and
other Unix systems (It is indeed a more powerful alternative to
docker) that makes package
management reliable and reproducible.
After setting up the project and playing around with it, we will parametrize
the project description in order to automatically build it with different
compilers and dependency library versions (GCC 7 & 8, Clang 7 & 8, lib
1.6.6 - 1.6.9, lib
poco 1.9.0 & 1.9.1).
While learning Haskell and using its really smart library dependency management tools (
stack), i realized that the C++ eco system has a problem:
There are no handy established tools that let the developer declare which libraries (and versions) are required for a project which can then be automatically installed in a portable way.
Nix however convinced me to be more versatile and powerful than Conan and handier than Docker, Vagrant, etc. (although it’s fair to say that i am mixing use cases here a little bit!)
In this article, i am going to showcase this great tool a little bit.
This article picks up an example operating system kernel code snippet that is written in C++, but looks like “C with classes”. I think it is a great idea to implement Embedded projects/kernels in C++ instead of C and it’s nice to see that the number of embedded system developers that use C++ is rising. Unfortunately, I see stagnation in terms of modern programming in embedded/kernel projects in the industry. After diving through the context i demonstrate how to implement a nice iterator as a zero cost abstraction that helps tidy up the code.
This article is about the C++17 STL Cookbook, which got published this week. After about 6 months of writing, I am happy that it is out the door and hope it helps and inspires its readers to write modern C++ code.
Sometimes, casting is just inevitable. And then there’s even not much science behind it, at least it seems so. Once some address is provided in a variable of the right size, a typed pointer can be casted out of it, and then the object can be accessed via its members and methods as usual. In some situations it is really easy to get the casting wrong, leading to interesting bugs. This article describes an example situation and a proper fix.
The C++ STL comes with stream style character output, which is an alternative to the classic
printf like format function collection of the C library.
For different reasons, some C++ programmers still stick to
printf like formatting.
This article demonstrates the
pprintpp (open source, and available on Github) library, which tries to make
printf use comfortable and safe while avoiding any runtime overhead.
There are a lot of algorithms which can be implemented using recursive or iterative style.
Actually, everything can be implemented in both styles.
For a lot of algorithms, the recursive version is simpler to read, write, and understand.
But nevertheless, programmers know, that recursive functions burden a lot of memory consumption, because there is usually a
call instruction per recursive call, which puts another call frame on the stack.
Interestingly, this is not true for some special cases.
Sometimes there is the requirement to generate a range of numbers from some algorithm. Be it a simple range of increasing numbers, or only odd numbers, or only primes, or whatever. Some calculations can be optimized by memorizing some values for the calculation of the next number, just as this applies for fibonacci numbers. This article shows how to wrap such calculations into iterators in order to have performant, and nicely encapsulated algorithms.
Soon, after writing my first meta programs with C++ templates, i realized, that certain programming patterns lead to sky rocketing compile times. I came up with rules of thumb like “Prefer pattern matching over if_else_t”, and “Prefer nested type lists over variadic type lists”. But i did not know how much faster which pattern is, i just knew about tendencies. Finally, i sat down to write some compile time benchmarks, and this blog posts presents the results.
In some situations, it can be useful ot generate sequences of numbers at compile time. This article shows how to generate integer sequences with C++ templates, and gives an example how to use it.
This article completes a series which aims at explaining how to implement a Brainfuck Interpreter as a template meta-program which runs at compile time.
Turing Machines consist of a tape with memory cells, a tape reader like cassette drives and a program table. Implementing the tape drive part with an array and a pointer is a trivial thing to do with imperative programming languages. It becomes more interesting when learning purely functional programming, especially in the context of template meta programming in C++. As a preparation for the next article, i will show how to implement a turing tape based on type lists, usable at compile time.
Type lists are an important way to represent ordered and unordered sets of types at compile time. These types can be real structure- or class types bundling runtime algorithms etc., but they can also convey actual data at compile time. In order to apply certain compile time processing to data, this data needs to be transformed from and to other representations, which can be provided by the programmer and consumed by run time programs. This article shows how to transform back and forth between strings and character type lists.
Homogenuous data in purely functional programs is typically managed in lists. Items can be appended or prepended to lists, different lists can be concatenated. Lists can be filtered, transformed, mapped, reduced, etc. Having all this nice stuff as a template meta library is quite an enabler for complex compile time meta programs.
C++ template meta programs are at first really hard to read. This is because the template mechanism accidentally became turing complete, although it was invented to enable for type-agnostic programming of generic algorithms. However, now the world knows that the C++ template part of the language is turing complete, people started writing full programs in it, and it enhances the power and flexibility of libraries quite a lot. This article aims to explain some very basic things one needs to know about the C++ template meta programming language, in order to be able to do things with it, or even understand foreign programs.
In both C and C++, it is not a sane idea to hold a reference (or a pointer in C) to a temporarily created object, as the reference is quickly dangling as soon as the assignment is done. But actually, C++ provides an interesting feature, where the life time of a temporary object can be extended to the life time of the reference which points to it.
What does actually happen, if an exception is thrown somewhere in the middle of a C++ program, but there is no try-catch clause which handles it? The program gets terminated. That is fine in general, but what happens to all objects which need to be properly destructed?
In order to use polymorphy, virtual functions are the way to go in C++. They are nice and easy to use. However, polymorphy is not always needed at actual runtime. If it is only used to separate generic from specific functionality in order to have a common interface and avoid code duplication, the cost of having indirection introduced by vtables might not be desired. This article shows how to use the CRTP in order to get the compile time advantages of polymorphy, without using virtual methods.
Some objects have different interfaces for doing the same thing in a different way. One could either check if two objects are equal, or if both are not different. Or one could ask if some container is empty, or if it has zero size. Classes should sometimes provide multiple kinds to express the same thing to let the user decide which way to express something is more readable in a specific context. But that does not mean, that the class developer has to express everything multiple times. This article explains how CRTP can help out and remove potential duplicate code lines.
When using C-style libraries, dealing with resources which need to be constructed and destructed again, the code doing the construction/allocation and destruction/release often ends up being ugly and repetitive, because one can’t easily stick with the RAII principle. Especially when a whole set of resources is allocated, and the case that some allocation inbetween fails, all already allocated resources need to be correctly released again. When wrapping such code in C++, it is possible to tidy such code paths up by using automatic destructor calls.
SFINAE type traits are very mighty, because they can check a lot of properties of types in a non-intrusive way. Unfortunately, they are extremely bloaty to implement. The single interesting expression within an SFINAE type trait is surrounded by lots of boiler plate code, which is ugly to read and repetitive. This article shows a nice one-liner approach to define new SFINAE type traits.
I happen to use the SDL library when i need to display graphics on the screen, but want to do it simpler than with OpenGL.
SDL is easy to use and portable, but it is a C-style library.
Because of that C nature, the library does not really help the user to write elegant, modern code.
Acquiring and Releasing SDL resources often ends up in ugly old school resource management.
It is not hard to fix that, and this article shows how useful
shared_ptr from the STL is in such cases.
The approach is easily extendable to other kinds of resources, too.
__FILE__ macro expands to the current source file name at compile time.
It is not really useful if the source file paths which the build system uses, are very long, as this would bloat log output with long path names.
It would be useful to have a shortened version, which only contains the file name without the whole path.
This article describes how to implement a
__SHORT_FILE__ macro, that does not add any run time overhead.
C++ type traits can be implemented using an interesting technique which uses the SFINAE principle. This article explains what SFINAE means, how it works and how it can be used to implement useful type traits.
This article explains, how so called type traits in C++ work. Type traits have been there for quite a long time now. They are a meta programming technique which appears to use types and their sub types like functions at compile time, to control what the compiler actually compiles.